MongoDB 6.0.3分片集群平衡异常与兼容性版本问题咨询
MongoDB分片集群问题排查与解答
背景
我们的标准副本集已达性能瓶颈,正在测试迁移至分片集群。已搭建MongoDB 6.0.3版本的全新分片集群(3个分片,每个分片含2个数据节点+1个仲裁节点),恢复了一个92 GiB(约1000万条文档)的样本集合,成功创建索引并执行分片命令:
sh.shardCollection( "saba_ludu.MyCollection", { UniqueId:"hashed" }, { collation: {locale : "simple"} } )
执行后集群完全未平衡,所有数据都在主分片上,执行sh.balancerCollectionStatus("saba_ludu.MyCollection")返回balancerCompliant: true。随后遇到异常:执行某命令时提示因集群兼容性版本过低无法执行(未手动配置过该版本),升级至兼容性版本6后,集合开始在分片间平衡并生成大量块,但主分片仍仅保留1个块,执行db.getSiblingDB("saba_ludu").MyCollection.getShardDistribution()的结果如下:
db.getSiblingDB("saba_ludu.MyCollection").getShardDistribution(); Shard i2a-poc-mgdb-cl-03 at i2a-poc-mgdb-cl-03/i2a-poc-mgdb-cl-03-0.i2a-poc-mgdb-cl-03-svc.i2a-poc.svc.cluster.local:27017,i2a-poc-mgdb-cl-03-1.i2a-poc-mgdb-cl-03-svc.i2a-poc.svc.cluster.local:27017 { data: '31.14GiB', docs: 3372644, chunks: 1, 'estimated data per chunk': '31.14GiB', 'estimated docs per chunk': 3372644 } --- Shard i2a-poc-mgdb-cl-02 at i2a-poc-mgdb-cl-02/i2a-poc-mgdb-cl-02-0.i2a-poc-mgdb-cl-02-svc.i2a-poc.svc.cluster.local:27017,i2a-poc-mgdb-cl-02-1.i2a-poc-mgdb-cl-02-svc.i2a-poc.svc.cluster.local:27017 { data: '30.87GiB', docs: 3344801, chunks: 247, 'estimated data per chunk': '127.99MiB', 'estimated docs per chunk': 13541 } --- Shard i2a-poc-mgdb-cl-01 at i2a-poc-mgdb-cl-01/i2a-poc-mgdb-cl-01-0.i2a-poc-mgdb-cl-01-svc.i2a-poc.svc.cluster.local:27017,i2a-poc-mgdb-cl-01-1.i2a-poc-mgdb-cl-01-svc.i2a-poc.svc.cluster.local:27017 { data: '30.86GiB', docs: 3344803, chunks: 247, 'estimated data per chunk': '127.94MiB', 'estimated docs per chunk': 13541 } --- Totals { data: '3.114100851894496e+23GiB', docs: 10062248, chunks: 495, 'Shard i2a-poc-mgdb-cl-03': [ '0 % data', '33.51 % docs in cluster', '9KiB avg obj size on shard' ], 'Shard i2a-poc-mgdb-cl-02': [ '0 % data', '33.24 % docs in cluster', '9KiB avg obj size on shard' ], 'Shard i2a-poc-mgdb-cl-01': [ '0 % data', '33.24 % docs in cluster', '9KiB avg obj size on shard' ] }
一、兼容性版本过低的原因
- 数据集版本继承:恢复的数据集来自低版本MongoDB(如5.x或更早),MongoDB为保证数据兼容性,会自动将集群的兼容性版本降级为原数据集的版本,即便你搭建的是6.0.3集群。
- 初始化同步异常:集群初始化时,配置服务器未正确同步版本信息,导致兼容性版本未自动设置为6.0,需手动触发升级。
- 部署参数默认配置:部分部署脚本或工具可能默认给分片节点指定了较低的兼容性版本启动参数,即便你未手动配置,也会导致版本不匹配。
二、主分片无法拆分块实现平衡的原因
结合哈希分片配置和块分布情况,主要原因如下:
- 兼容性升级遗留元数据问题
兼容性版本未升级时,Balancer无法正常工作,主分片的超大块未被标记为需要拆分。升级后,Balancer优先处理新生成的块迁移,但初始大块的元数据未被更新,未进入拆分队列。 - 资源限制导致拆分延迟
31GiB的块拆分需要消耗大量CPU、内存和磁盘IO资源,如果集群在平衡过程中资源紧张,MongoDB会优先处理较小的块迁移,暂时延迟超大块的拆分。 - 哈希分片初始块特殊状态
哈希分片的初始块覆盖整个哈希值范围,虽然数据量远超默认chunkSize(64MB),但如果块内文档的哈希值分布存在极端集中的情况,可能导致自动拆分失败——不过从其他分片的块大小正常来看,这个可能性较低。
排查与解决建议
- 检查块元数据状态:执行
sh.status()查看主分片块的范围和标记,确认是否被标记为可拆分。 - 手动触发块拆分:对主分片的大块执行手动拆分命令,例如:
// 选择主分片块中存在的UniqueId值作为拆分点 sh.splitFind("saba_ludu.MyCollection", {UniqueId: "某个存在的ID值"}) - 验证集群资源:查看主分片节点的CPU、内存、磁盘IO指标,确认是否存在资源瓶颈。
- 确认兼容性版本全集群生效:执行以下命令,确保所有节点的兼容性版本均为6.0:
db.adminCommand({getParameter: 1, featureCompatibilityVersion: 1})
内容的提问来源于stack exchange,提问作者luke77
相关产品推荐
相关产品推荐

