分片集群平衡器

在本页面

MongoDB 平衡器是一个后台进程,它监视每个shard上的chunks的数量。当给定分片上的块数达到特定migration thresholds时,平衡器将尝试在分片之间自动迁移块,并使每个分片上的块数均相等。

sharded clusters的平衡过程对于用户和应用程序层完全透明,尽管在进行过程中可能会影响性能。

分布在三个碎片上的集合图。对于此集合,分片之间的块数量差异达到迁移阈值(在这种情况下为 2)并触发迁移。

从 MongoDB 3.4 开始,平衡器在配置服务器副本集(CSRS)的主数据库上运行:

  • 在版本 3.4 中,当平衡器进程处于活动状态时,配置服务器副本集的主数据库通过修改Config Database中的locks集合中的_id: "balancer"文档来获取“平衡器锁”。永远不会释放此“平衡器锁”。

  • 从 3.6 版开始,平衡器不再需要“锁定”。

Cluster Balancer

balancer进程负责为每个分片集合在分片之间平均分配分片集合的块。默认情况下,平衡器进程始终处于启用状态。

在版本 3.4 中进行了更改:平衡器在配置服务器副本集的主数据库上运行。当平衡器进程处于活动状态时,配置服务器副本集的主数据库通过修改Config Databaselock集合中的文档来获取“平衡器锁”。永远不会释放此“平衡器锁”。

为了解决分片集合的不均匀分块分布,平衡器migrates chunks从具有更多分块的分片到具有更少分块的分片。平衡器将迁移块,直到整个碎片中的集合的块均匀分布为止。有关块迁移的详细信息,请参见块迁移程序

在 2.6 版中进行了更改:块迁移可能会影响磁盘空间。从 MongoDB 2.6 开始,源碎片默认情况下会自动存档迁移的文档。有关详细信息,请参见moveChunk directory

块迁移会带来一些带宽和工作负载方面的开销,这两者都会影响数据库性能。 balancer尝试通过以下方式最大程度地减少影响:

  • 在任何给定时间将一个分片限制为最多只能进行一次迁移;即一个分片不能同时参与多个块迁移。要从一个分片迁移多个块,平衡器一次迁移一个块。

在版本 3.4 中进行了更改:从 MongoDB 3.4 开始,MongoDB 可以执行并行块迁移。遵守分片每次最多只能参与一次迁移的限制,对于具有* n 个分片的分片集群,MongoDB 最多可以同时执行 n/2 *(向下舍入)的块迁移。

另请参见异步块迁移清理

  • 仅在分片集合的具有最大块数的分片与该集合的具有最小块数的分片之间的块数之差达到migration threshold时,才开始平衡回合。

您可以暂时禁用平衡器进行维护。有关详情,请参见禁用平衡器

您还可以限制平衡器运行的窗口,以防止其影响生产流量。有关详情,请参见安排平衡窗口

Note

平衡窗口的规范是相对于配置服务器副本集主数据库的本地时区的。

从集群添加和删除分片

将分片添加到群集会造成不平衡,因为新分片没有任何块。当 MongoDB 立即开始将数据迁移到新的分片时,群集平衡可能需要一些时间。有关将分片添加到集群的说明,请参见将分片添加到集群教程。

从集群中删除一个分片也会造成类似的不平衡,因为该分片上的数据块必须重新分配到整个集群中。当 MongoDB 立即开始耗尽已删除的分片时,集群可能需要一些时间才能达到平衡。 请勿在此过程中关闭与已删除的分片关联的服务器。

当您在块分布不均匀的群集中删除一个分片时,平衡器首先从排水分片中删除这些块,然后平衡其余的不均匀块分布。

有关从群集中安全删除碎片的说明,请参见从现有分片群集中删除分片教程。

批量迁移程序

所有块迁移均使用以下过程:

  • 平衡器进程将moveChunk命令发送到源分片。

  • 源使用内部moveChunk命令开始移动。在迁移过程中,对块的操作将路由到源分片。源碎片负责该块的传入写操作。

  • 目标分片将构建目标上不存在的源所需的所有索引。

  • 目标分片开始请求块中的文档,并开始接收数据的副本。另请参见块迁移和复制

  • 在接收到块中的最终文档之后,目标分片将启动同步过程,以确保它具有对迁移期间发生的已迁移文档的更改。

  • 完全同步后,源分片将连接到config database并使用该块的新位置更新群集元数据。

  • 在源分片完成元数据的更新之后,并且一旦块上没有打开的游标,源分片就会删除其文档副本。

Note

如果平衡器需要从源碎片执行其他块迁移,则平衡器可以开始下一个块迁移,而无需 await 当前的迁移过程完成此删除步骤。参见异步块迁移清理

迁移过程可确保一致性,并在平衡期间最大程度地利用块。

Migration Thresholds

为了最大程度地减少平衡对集群的影响,balancer仅在分片集合的块分配达到特定阈值后才开始平衡。阈值适用于集合中具有最多块的碎片与该集合中具有最少块的碎片之间的chunks数量之差。平衡器具有以下阈值:

块数Migration Threshold
少于 202
20-794
80 及更高8

当该集合的任何两个分片上的块数之差小于* 2 时,平衡器将停止在目标集合上运行,或者块迁移失败。

异步块迁移清理

要从一个分片迁移多个块,平衡器一次迁移一个块。但是,平衡器在开始下一个块迁移之前不会 await 当前迁移的删除阶段完成。有关块迁移过程和删除阶段,请参见Chunk Migration

这种排队行为使分片在集群严重不平衡的情况下可以更快地卸载块,例如在不进行预拆分的情况下执行初始数据加载以及添加新分片时。

此行为也会影响moveChunk命令,并且使用moveChunk命令的迁移脚本可能会更快地进行。

在某些情况下,删除阶段可能会持续更长时间。如果多个删除阶段处于排队状态,但尚未完成,则副本集主数据库的崩溃可能会使来自多个迁移的数据孤立。

_waitForDelete(可以用作平衡器的设置以及moveChunk命令)可以更改行为,以使当前迁移的删除阶段阻止下一个块迁移的开始。 _waitForDelete通常用于内部测试。有关更多信息,请参见await 删除

块迁移和复制

在版本 3.4 中更改。

在块迁移期间,_secondaryThrottle值确定何时对块中的下一个文档进行迁移。

config.settings集合中:

  • 如果将平衡器的_secondaryThrottle设置设置为写关注,则在 continue 下一个文档之前,块迁移期间的每个文档移动都必须收到请求的确认。

  • 如果将平衡器的_secondaryThrottle设置设置为true,则在迁移 continue 进行块中的下一个文档之前,在块迁移期间移动的每个文档都必须至少从一个辅助节点收到确认。这等效于{ w: 2 }的写入关注。

  • 如果未设置_secondaryThrottle设置,则迁移过程将不 await 复制到辅助数据库,而是 continue 下一个文档。

从 MongoDB 3.4 开始,WiredTiger的默认行为。

对于moveChunk命令,可以使用命令的_secondaryThrottlewriteConcern选项指定命令执行期间的行为。有关详细信息,请参见moveChunk命令。

与任何_secondaryThrottle设置无关,块迁移的某些阶段具有以下复制策略:

  • 在使用新的块位置更新配置服务器之前,MongoDB 会在源分片上暂时暂停所有正在迁移的应用程序的读写操作,并在更新后恢复应用程序的读写操作。块移动要求在将块移动提交到配置服务器之前和之后,副本集的大多数成员都应确认所有写入。

  • 当外发块迁移完成并进行清理后,必须将所有写操作复制到大多数服务器上,然后再进行进一步清理(来自其他外发迁移)或 continue 进行新的外来迁移。

要更新config.settings集合中的_secondaryThrottle设置,请参见Secondary Throttle为例。

每块要迁移的最大文档数

在版本 3.4.11 中进行了更改。

如果块中的文档数大于配置的chunk size除以平均文档大小所得结果的 1.3 倍,则 MongoDB 无法移动该块。 db.collection.stats()包含avgObjSize字段,该字段表示集合中的平均文档大小。

Shard Size

默认情况下,随着数据集的增长,MongoDB 尝试使用每个分片上的数据填充所有可用磁盘空间。为确保群集始终具有处理数据增长的能力,请监视磁盘使用情况以及其他性能 Metrics。

有关设置分片最大大小的说明,请参见更改给定分片的最大存储大小教程。