全部产品
Search
文档中心

云数据库 MongoDB:管理MongoDB均衡器Balancer

更新时间:Sep 09, 2026

在云数据库 MongoDB 版分片集群实例增删Shard节点、数据迁移等场景下,您可能需要修改均衡器Balancer的活动窗口期或开启关闭均衡器Balancer。本文介绍如何管理均衡器Balancer。

功能简介

均衡器Balancer用于均衡分片集群实例中各Shard节点中的数据,不同版本的MongoDB实例工作原理存在区别:

  • MongoDB 5.0及以前版本:

    Balancer会监控分片集群实例中各个Shard节点上的Chunk(块)数量,当某个Shard节点上的Chunk数量达到迁移阈值时,Balancer会对Shard节点上的Chunk进行迁移(moveChunk),尽量保证每个Shard节点上的Chunk数量相同。不同版本的迁移阈值存在差异,具体信息如下。

    数据库版本

    迁移阈值

    MongoDB 3.2(已停售)

    • Chunk总数<20,迁移阈值为2。

    • 20≤Chunk总数≤80,迁移阈值为4。

    • 80≤Chunk总数,迁移阈值为8。

    MongoDB 3.4(已停售)

    MongoDB 4.0

    • 默认迁移阈值为2。

    • 如果Chunk总数小于20个,或者上次迁移的Chunk数量小于20个,迁移阈值为1。

    MongoDB 4.2

    MongoDB 4.4

    MongoDB 5.0

    迁移阈值为1。

  • MongoDB 6.0 及以后版本:

    由于Jumbo Chunk的存在,根据Chunk数量均衡数据可能会出现各Shard节点上Chunk数量相同,但是磁盘空间使用大小却不同的情况。为解决上述问题,自云数据库 MongoDB 版6.0版本起,Balancer变为监控分片集群实例中各个Shard节点上同一集合的数据大小情况,当集合在各Shard节点上的数据大小差异超过384 MB时(三倍的Chunk Size),Balancer会根据Shard Tag分割数据再迁移(moveRange)至其他Shard节点。

    如果您需要判断数据是否均衡,可以通过getShardDistribution()命令查看集合的数据分布情况,无需再关注Chunk这个逻辑概念,只需专注于集合数据大小即可。

    说明

    升级到6.0版本(小版本7.0.1及以上)或更高版本后,您可能会发现通过sh.status()查看到各Shard上的Chunk数量不再均衡,甚至合并为1个,这是新版本Balancer的正常行为。详情请参见升级MongoDB实例后,各分片Chunks数量不均衡。

注意事项

  • 仅分片集群实例支持Balancer功能。

  • Balancer默认处于开启状态。如未开启,请参见开启Balancer功能。

  • Balancer的活动窗口期默认为全天,当Balancer执行块迁移时,可能会影响数据库性能。为避免块迁移给您的业务带来影响,建议您将Balancer的活动窗口期修改为业务低峰期。设置活动窗口期的方法,请参见设置Balancer的活动窗口。

  • 本文的示例均通过Mongo Shell进行操作,其他客户端工具管理Balancer的方法以及返回信息可能与本文示例存在差异。

设置Balancer的活动窗口

  1. 通过Mongo Shell连接MongoDB分片集群实例。

  2. 在mongos节点命令窗口中,切换至config数据库。

    use config
  3. 执行如下命令设置Balancer的活动窗口。

    db.settings.update(
       { _id: "balancer" },
       { $set: { activeWindow : { start : "<start-time>", stop : "<stop-time>" } } },
       { upsert: true }
    )
    说明
    • <start-time>:开始时间,时间格式为HH:MM(实例所在地域的当地时间),HH取值范围为00~23,MM取值范围为00~59。

    • <stop-time>:结束时间,时间格式为HH:MM(实例所在地域的当地时间),HH取值范围为00~23,MM取值范围为00~59。

    例如,您需要将Balancer活跃窗口期修改为每天凌晨的1点到3点,示例如下:

    db.settings.update(
       { _id: "balancer" },
       { $set: { activeWindow : { start : "01:00", stop : "03:00" } } },
       { upsert: true }
    )

    设置成功后,您可以执行sh.status()命令查看Balancer的活动窗口。返回示例如下。

相关操作:如您需要Balancer始终处于运行状态,您可以执行如下命令去除活动窗口的设置。

db.settings.update({ _id : "balancer" }, { $unset : { activeWindow : true } })                

开启Balancer功能

如果您设置了数据分片,开启Balancer功能后可能会立即触发均衡任务。这将占用实例的资源,请在业务低峰期执行该操作。

  1. 通过Mongo Shell连接MongoDB分片集群实例。

  2. 在mongos节点命令窗口中,切换至config数据库。

    use config
  3. 执行如下命令开启Balancer功能。

    sh.setBalancerState(true)

关闭Balancer功能

均衡器Balancer默认处于开启状态。如果需临时关闭,请参见以下步骤进行操作。

说明

关闭Balancer功能后,Balancer将不会再均衡各Shard节点中的数据,可能会导致数据倾斜。

  1. 通过Mongo Shell连接MongoDB分片集群实例。

  2. 在mongos节点命令窗口中,切换至config数据库。

    use config
  3. 执行sh.isBalancerRunning()命令查看Balancer运行状态。

    sh.isBalancerRunning()命令会依据Mongo Shell客户端的版本返回不同的结果,返回结果目前有布尔值和Map两种:

    • 布尔值

      • 返回值为false,表示Balancer没有处于执行任务的状态,此时可执行关闭Balancer操作。

      • 返回值为true,表示Balancer正在执行块迁移,此时不能执行关闭Balancer的命令,否则可能引起数据不一致。

    • Map

      {
        mode: 'full',
        inBalancerRound: false,
        numBalancerRounds: Long("1143"),
        ok: 1,
        '$clusterTime': {
           clusterTime: Timestamp({ t: 1639753724, i: 3 }),
           signature: {
              hash: Binary(Buffer.from("0000000000000000000000000000000000000000", "hex"), 0),
              keyId: Long("0")
           }
        },
        operationTime: Timestamp({ t: 1639753724, i: 3 })
      }
      • 如果inBalancerRound为false,表示Balancer没有处于执行任务的状态,此时可执行关闭Balancer操作。

      • 如果inBalancerRound为true,表示Balancer正在执行块迁移,此时不能执行关闭Balancer的命令,否则可能引起数据不一致。

    更多关于sh.isBalancerRunning()的介绍,请参见sh.isBalancerRunning()。

  4. 确认执行第3步的命令后返回的值为空,可执行关闭Balancer命令。

    sh.stopBalancer()

常见问题

开启均衡器 Balancer 后产生孤儿文档是否正常及如何处理

开启均衡器 Balancer 后出现孤儿文档,通常是因为 Chunk 迁移中断、回滚,或者分片键分布异常,导致 moveChunk 操作残留数据。

Balancer 频繁迁移 Chunk 期间,孤儿文档数量短暂波动属于正常现象。只要 Chunk 迁移结束后孤儿文档数量最终降为 0,且孤儿文档并非长期持续存在,通常无需担心。

当集合间的数据量差异超过默认阈值(例如 200 多 MB)时,会自动触发均衡。该均衡过程中可能短暂产生孤儿文档。

如果孤儿文档长期存在,请按以下顺序排查和处理:

  1. 检查 Balancer 日志,确认是否存在 Chunk 迁移异常。

  2. 检查分片键是否合理,确保数据分布均匀。

  3. 确认 Chunk 迁移完成后,执行 cleanupOrphaned 命令清理孤儿文档。