在分片群集上建立滚动索引
在本页面
索引构建会影响分片集群的性能。默认情况下,MongoDB 4.4及以后版本在所有承载数据的复制集成员上同时构建索引。基于分片集群的索引仅发生在那些包含被索引的集合数据的分片上。对于不能容忍由于索引构建而导致性能下降的工作负载,可以考虑使用以下过程以滚动方式构建索引。
滚动索引构建一次最多取出一个碎片复制集成员(从辅助成员开始),并在该成员上作为一个独立的成员构建索引。构建滚动索引需要每个碎片至少进行一次复制集选择。
- 用于构建唯一索引1.要使用以下过程创建唯一索引,必须在索引生成期间停止对集合的所有写操作。否则,复制集成员之间的数据可能会不一致。如果 不能停止对集合的所有写操作,请不要使用以下过程创建唯一索引。警告如果不能停止对集合的所有写操作,请不要使用以下过程创建唯一索引。2.在创建索引之前,验证集合中没有文档违反索引约束。如果一个集合分布在多个切片上,而一个切片中包含有重复文档的块,那么 创建索引操作可能在没有重复的切片上成功,但在有重复的切片上失败。为了避免在多个碎片之间留下不一致的索引,可以从 mongos中发出
db.collection.dropIndex()
来从集合中删除索引。
重要以下以滚动方式构建索引的过程适用于分片集群部署,而不适用于复制集部署。关于复制集的过程,请参见复制集上的滚动索引构建。
sh.stopBalancer()
注意如果迁移正在进行中,系统将在停止平衡器之前完成迁移。
sh.getBalancerState()
在
mongo
shell连接程序 mongos
,刷新缓存的路由表, mongos
以免返回该集合的陈旧分发信息。刷新后,运行 db.collection.getShardDistribution()
要构建索引的集合。例如,如果您想在
test
数据库的records
集合上使用升序索引:db.adminCommand( { flushRouterConfig: "test.records" } );
db.records.getShardDistribution();
该方法输出切分分布。例如,考虑一个分片集群,有3个分片**' shardA '、' shardB '和' shardC '**, ' db.collection.getShardDistribution() '返回以下结果:
Shard shardA at shardA/s1-mongo1.example.net:27018,s1-mongo2.example.net:27018,s1-mongo3.example.net:27018
data : 1KiB docs : 50 chunks : 1
estimated data per chunk : 1KiB
estimated docs per chunk : 50
Shard shardC at shardC/s3-mongo1.example.net:27018,s3-mongo2.example.net:27018,s3-mongo3.example.net:27018
data : 1KiB docs : 50 chunks : 1
estimated data per chunk : 1KiB
estimated docs per chunk : 50
Totals
data : 3KiB docs : 100 chunks : 2
Shard shardA contains 50% data, 50% docs in cluster, avg obj size on shard : 40B
Shard shardC contains 50% data, 50% docs in cluster, avg obj size on shard : 40B
从输出中,您只为
test
构建索引。记录在shardA
和shardC
。对于包含集合块的每个分片,遵循以下过程在分片上构建索引。
- 配置文件
如果您正在使用配置文件,请进行以下配置更新:
- 在设置参数部分将参数disableLogicalSessionCacheRefresh设置为true。
例如,对于一个分片复制集成员,更新后的配置文件将包括如下示例所示的内容:
net:
bindIp: localhost,<hostname(s)|ip address(es)>
port: 27218
# port: 27018
#replication:
# replSetName: shardA
#sharding:
# clusterRole: shardsvr
setParameter:
skipShardingConfigurationChecks: true
disableLogicalSessionCacheRefresh: true
并重新启动:
mongod --config <path/To/ConfigFile>
- 命令行选项
如果使用命令行选项,请进行以下配置更新:
例如,重新启动不带
--replSet
和 --shardsvr
选项的分片副本集成员。指定新的端口号,并将skipShardingConfigurationChecks
和 disableLogicalSessionCacheRefresh
参数都设置 为true:mongod --port 27218 --setParameter skipShardingConfigurationChecks=true --setParameter disableLogicalSessionCacheRefresh=true
db.records.createIndex( { username: 1 } )
重要
例如,重新启动你的复制集分片成员:
- 配置文件
如果您正在使用配置文件,请进行以下配置更新:
- 恢复为原始端口号。
net:
bindIp: localhost,<hostname(s)|ip address(es)>
port: 27018
replication:
replSetName: shardA
sharding:
clusterRole: shardsvr
并重新启动:
mongod --config <path/To/ConfigFile>
- 命令行选项
如果使用命令行选项,请进行以下配置更新:
- 恢复为原始端口号。
- 删除参数
disableLogicalSessionCacheRefresh
。
例如:
mongod --port 27018 --replSet shardA --shardsvr
一旦该成员赶上了集合中的其他成员,就对分片中剩余的次要成员一次重复这 个过程:
- 2.
当分片的所有辅助数据库都具有新索引时,请降低分片的主数据库,使用上述步骤以独立方式重新启动它,然后在前一个主数据库上建立索引:
- 1.
- 3.
为受影响的分片完成滚动索引构建后,重新启动平衡器。
sh.startBalancer()
如果在包含集合块的每个分片上没有完全相同的索引(包括索引选项),则分片集合具有不一致的索引。虽然在正常操作中不应该出现索引不一致的情况,但也会出现索引不一致的情况,例如:
- 当用户正在创建一个索引,一个“唯一”的关键约束和一个分片包含块与重复的文档。在这种情况下,创建索引操作可能在没有重复的分片上成功,但在有重复的切分上失败。
- 当用户以滚动方式在多个切片之间创建索引,但要么未能为关联的切片建立索引,要么不正确地建立了不同规格的索引。
从MongoDB 4.4(和4.2.6)开始,配置服务器主服务器会定期检查分片集合中各分片之间的索引不一致。要配置这些定期检查,请参阅
enableShardedIndexConsistencyCheck
和 shardedIndexConsistencyCheckIntervalMS
。最近更新 1yr ago