降低Config Server负载需从“少读、少写、少扫”入手,核心是减少config.chunks集合的文档数量,避免小chunk碎片化,合并相邻小chunk,禁用不用数据库,并确保均衡器正常运行。

sh.getShardDistribution() 返回的 chunks 字段就是你要的总数
直接在 mongos shell 中执行 sh.getShardDistribution("your_collection"),输出里每行的 chunks 列是该 shard 当前持有的 chunk 数量,最后一行的汇总(如果有)或手动加总所有 chunks 值,就是整个集合当前的 chunk 总数。
注意:sh.getShardDistribution() 不统计 config server 上的系统集合(如 config.chunks 本身),它只反映用户集合在各数据分片上的实际分布。如果你要查的是“集群里一共定义了多少个 chunk”,那得查 config.chunks 集合——但这个数字可能包含已删除集合残留的 chunk 记录,不具备实时业务意义。
查 config.chunks 集合时必须加 $ne: null 过滤掉无效记录
直接运行 db.getSiblingDB("config").chunks.find().count() 得到的数字往往偏高,因为 config.chunks 里可能存有已删除集合的残留条目、或迁移中断后未清理的孤儿 chunk。真正有效的 chunk 必须满足两个条件:有非空的 min 和 max 字段,且 shard 字段存在且不为空。
- 安全查询方式:
db.getSiblingDB("config").chunks.countDocuments({ "min": { "$ne": null }, "max": { "$ne": null }, "shard": { "$exists": true, "$ne": "" } }) - 如果只想看某个分片(比如
shard01)上归属它的有效 chunk 数:db.getSiblingDB("config").chunks.countDocuments({ "shard": "shard01", "min": { "$ne": null }, "max": { "$ne": null } }) - 查 jumbo chunk 数量(这些 chunk 已无法分裂,会影响均衡):
db.getSiblingDB("config").chunks.countDocuments({ "jumbo": true })
chunk 数量突增或长期不降,大概率是 balancer 被停了或卡住了
正常运行的分片集群中,chunk 数量会在 balancer 活跃时动态波动,但整体维持在一个合理区间(比如 20–200 之间,取决于数据量和 chunkSize)。如果发现数量持续上涨且不再下降,先确认 balancer 状态:
- 运行
sh.getBalancerState()—— 返回true才表示开启 - 运行
sh.isBalancerRunning()—— 返回true表示当前正在迁移中 - 查迁移锁:
db.getSiblingDB("config").locks.findOne({ "_id": "balancer" }),若state是2(锁住)且who字段非空,说明某次迁移卡死,需人工干预
另外,sh.status() 输出末尾的 “balancer” 小节会显示最近一次成功迁移时间,超过 1 小时没动静就值得排查。
监控脚本里别用 db.collection.stats().shards —— 它根本不存在
有人误以为 db.collection.stats() 返回结果里会有 shards 字段,实际上该命令在分片集群中只返回当前路由到的那个分片(通常是 primary shard)的局部统计,字段里压根没有 shards 或 chunkCount 这种东西。硬取会报 undefined 或静默失败。
真正能稳定获取 chunk 分布的只有两个入口:
-
sh.getShardDistribution():适合人工巡检或简单脚本,MongoDB ≥ 4.2 - 直查
config.chunks:适合自动化监控、告警逻辑,兼容所有版本,但必须自己过滤脏数据
别在监控项里混用 stats() 和 getShardDistribution(),前者永远不反映全局,后者才是唯一靠谱的聚合视图。


















