MongoDB一个广为诟病的问题是,大量数据resotore时索引重建非常缓慢,实测5000万的集合如果有3个以上的索引需要恢复,几乎没法成功,而且resotore时如果选择创建索引也会存在索引不生效的问题,种种情况表明,MongoDB的一些默认设置存在明显不合理之处。
当然,深入理解后总会有办法解决这些问题,MongoDB发展到金,功能也是越来全面。
一、对于小数据量collection,可直接单命令行创建索引
类似如下操作:
db.getCollection('processDataObj').createIndex({ 'flowNo':1 }, {}, 'majority')
二、对于大数据量collection,需执行后台创建的方式
如下是最佳实践脚本:
echo "定义变量..."
COLLECT="processDataObjInit"
INDEX="'flowNo':1"
JSFILE=processDataObjInit_1.js
echo "生成js文件..."
echo "print('createIndex ...');
print(db.${COLLECT}.createIndex({${INDEX}}, {}, 'majority'));
print('End time is:');
print(db.hello());" > ${JSFILE}
echo "执行后台创建索引..."
JSFILE=processDataObjInit_1.js
KKLOG=${JSFILE}-`date +%Y-%m-%dT%H:%M`.log
mongosh mongodb://'admin':'passwd'@node1:20000,node2:20000,node3:20000/flowtest?authSource=admin --quiet ${JSFILE} > $KKLOG 2>&1 &
三、4600万collection重建索引计时情况
-rw-rw-r-- 1 mongod mongod 140 10月 8 15:32 processDataObjInit_1.js
-rw-rw-r-- 1 mongod mongod 707 10月 8 16:20 processDataObjInit_1.js-2023-10-08T15:32.log
-rw-rw-r-- 1 mongod mongod 184 10月 8 15:31 processDataObjInit_2.js
-rw-rw-r-- 1 mongod mongod 746 10月 8 16:20 processDataObjInit_2.js-2023-10-08T15:31.log
-rw-rw-r-- 1 mongod mongod 223 10月 8 15:28 processDataObjInit_3.js
-rw-rw-r-- 1 mongod mongod 782 10月 8 16:20 processDataObjInit_3.js-2023-10-08T15:28.log
可见基本需要50分钟左右即可并发完成3个索引的创建。
四、MongoDB默认只能同时并发创建3个索引
因此需修改配置到制定的大小,本次案例有6个大索引需要同时创建,修改shard配置文件,调整并发为6.
setParameter:
maxNumActiveUserIndexBuilds: 6
实际启动shard时可以看到,配置已生效:
{"t":{"$date":"2023-10-08T07:01:54.495Z"},"s":"I", "c":"CONTROL", "id":5760901, "ctx":"main","msg":"Applied --setParameter options","attr":{"serverParameters":{"connPoolMaxConnsPerHost":{"default":200,"value":20000},"maxNumActiveUserIndexBuilds":{"default":3,"value":6}}}}