MongoDB分片集群中需用sh.stopBalancer()和sh.startBalancer()手动控制Balancer启停,配合系统级定时任务实现维护窗口;旧版时间配置字段已废弃,仅enabled布尔值有效。

如何在 MongoDB 分片集群中临时禁用和启用 Balancer
Balancer 不是“定时任务”,也没有原生的“维护窗口”配置项;它默认持续运行,只要满足条件(如 chunk 分布不均、迁移阈值被触发)就会自动启动迁移。所谓“设置维护窗口”,本质是手动控制 balancer 的启停状态,并配合时间调度工具实现周期性开关。
使用 sh.stopBalancer() 和 sh.startBalancer() 控制开关
这两个命令直接作用于整个集群的 Balancer 状态,执行后立即生效(无需重启进程),但仅在当前 mongos 会话中持久——实际效果是写入 config 数据库的 settings 集合,所有 mongos 共享该状态。
-
sh.stopBalancer():暂停 Balancer,已开始的迁移会继续完成,但不再发起新迁移 -
sh.startBalancer():恢复 Balancer,下次检查周期(默认 10 秒)后可能立即触发迁移 - 执行前建议先用
sh.getBalancerState()确认当前状态,避免重复操作 - 若集群正在执行迁移,
sh.stopBalancer()不会中断它,需等moveChunk完成或超时(默认 6 小时)
结合 cron 或 systemd timer 实现“定时维护窗口”
MongoDB 本身不提供 cron 功能,必须依赖操作系统级调度。关键点在于:命令需通过 mongosh 连接任意 mongos 并执行,且账号需有 clusterManager 角色权限。
- 示例(Linux cron):每天凌晨 2:00–4:00 关闭 Balancer
0 2 * * * /usr/bin/mongosh --host mongos01:27017 --eval "sh.stopBalancer()" --quiet0 4 * * * /usr/bin/mongosh --host mongos01:27017 --eval "sh.startBalancer()" --quiet - 务必使用
--quiet避免输出干扰 cron 日志 - 不要在多个 mongos 上并行执行 start/stop,虽然最终状态一致,但可能因网络延迟导致短暂不一致判断
- 生产环境建议加简单健康检查,例如:
sh.status().balancer.enabled返回 true/false 验证是否生效
为什么不能只靠 balancerStart/StopTime 配置?
旧版文档曾提过 balancerStartWindow 等参数,但这是 **config.settings** 中已废弃的字段(3.4+ 版本起忽略),现在只保留 enabled 布尔值。试图写入 start/stopTime 不会报错,但 Balancer 完全不读取它们。
- 查看真实配置:运行
db.getSiblingDB("config").settings.findOne({ _id: "balancer" }) - 合法字段只有
_id、enabled、mode(可选full或off,后者等价于enabled: false) - 任何自定义时间字段会被静默忽略,别浪费时间调试
Balancer 的启停不是原子操作,尤其在大集群中,从 stop 到真正无新迁移发起可能存在数秒延迟;如果维护窗口极短(比如 5 分钟),建议提前 2 分钟 stop,并在窗口结束前 1 分钟 start,留出缓冲。











