最新下载
热门教程
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
如何监控MongoDB分片集群的平衡器状态_使用sh.status查看Balancer活动窗口
时间:2026-07-02 11:04:52 编辑:袖梨 来源:一聚教程网
sh.status()中balancer部分仅显示是否启用、是否运行中、最近成功迁移时间;不反映待迁移chunk、队列状态、延迟或分布偏差,诊断需查config.migrationHistory、mongos日志及config.chunks聚合统计。
sh.status() 返回的 balancer 部分到底在说什么
直接看 sh.status() 输出里 balancer 段,核心就三件事:是否启用、是否正在运行、最近一次成功迁移时间。它不告诉你“接下来要搬哪块 chunk”,也不显示排队中的迁移任务——这些得查 config 数据库或日志。
常见误解是把 "enabled": true 当成“此刻正在搬数据”,其实只是开关打开;而 "currentlyRunning": true 才代表有迁移任务在执行中(哪怕只有一条)。
-
"enabled": false表示平衡器被手动停用(sh.stopBalancer()),即使集群严重倾斜也不会自动处理 -
"currentlyRunning": true但"activeWindow": null,说明没设活动窗口,平衡器全天候工作 - 若
"lastSeen": "..."时间戳超过 1 小时,大概率迁移卡住了,得查config.migrationHistory或mongos日志里的moveChunk错误
活动窗口(activeWindow)不是定时任务,而是白名单时间段
activeWindow 是平衡器“允许干活”的时间范围,并非 cron 式调度。它只控制迁移启动时机,不中断已在进行的迁移。一旦迁移开始,就算超出窗口也会跑完。
设置方式是调用 sh.setBalancerWindow(),传入 UTC 时间段(注意不是本地时区):
sh.setBalancerWindow( { start: "22:00", stop: "06:00" } )
这个配置写在 config.settings 集合里,所有 mongos 共享。如果多个 mongos 同时执行该命令,后写的会覆盖前写的——没有合并逻辑。
- 时间格式必须是
"HH:MM",不支持秒、时区缩写或 AM/PM - 跨日区间(如
"22:00"到"06:00")是合法的,内部按 UTC 处理 - 删掉窗口只需设为
null:sh.setBalancerWindow(null),别用空对象 - 修改后不会立即生效,下一个平衡周期(默认 10 分钟检查一次)才读取新配置
为什么 sh.status() 里看不到迁移延迟或 chunk 分布偏差
sh.status() 的 balancer 块是状态快照,不是监控仪表盘。它不包含实时负载、延迟、chunk 数量差值等指标——那些得自己算。
比如判断是否失衡,不能只看 "currentlyRunning": false,还要查各 shard 的 chunk 总数:
db.getSiblingDB("config").chunks.aggregate([ { $group: { _id: "$shard", count: { $sum: 1 } } } ])
再结合 db.getSiblingDB("config").tags.find() 看分片标签规则,才能确认是不是策略导致的“假失衡”。
- 平衡器默认每 10 分钟触发一次检查,但实际迁移频率受
chunkSize、网络延迟、目标 shard 磁盘压力影响,sh.status()不反映这些 - 如果某次
moveChunk失败(如目标 shard 写满),错误只记在mongos日志和config.migrationHistory,sh.status()里只会显示"lastSeen"停滞 -
sh.status()输出的"migrationCount"是历史累计值,不是当前队列长度,无法用于判断积压
停用平衡器时,sh.stopBalancer() 和直接改 config.settings 效果不同
sh.stopBalancer() 是安全停用:它先等待当前迁移完成,再更新 config.settings 并广播给所有 mongos。而手动 update config.settings 里的 balancer 文档,会立刻生效但可能中断迁移,导致数据不一致或锁残留。
恢复时也一样:sh.startBalancer() 会校验集群健康状态(如所有 shard 可达),而直接改回 "enabled": true 不做任何检查。
- 生产环境停平衡器务必用
sh.stopBalancer(),别绕过 shell 封装 - 停用期间新增的 chunk(如 bulk insert)不会被自动切分,等重启后才会参与平衡——这点常被忽略
- 如果
sh.stopBalancer()卡住超过 30 秒,大概率有迁移阻塞,需查config.locks里"_id": "balancer"的state字段是否为2(表示被其他操作锁住)
sh.status() 隐藏了太多上下文依赖:时间窗口的 UTC 语义、迁移中断的边界条件、停用操作的原子性保障。真要靠它诊断问题,得随时准备好翻 config.migrationHistory 和 mongos 日志。