管理MongoDB均衡器Balancer

云数据库 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这个逻辑概念,只需专注于集合数据大小即可。

注意事项

  • 仅分片集群实例支持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 })
      }
      • 如果inBalancerRoundfalse,表示Balancer没有处于执行任务的状态,此时可执行关闭Balancer操作。

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

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

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

    sh.stopBalancer()