平衡器

MongoDB平衡器是一个后台进程,用于监视每个分片上的块数。

当给定分片上的块数达到特定迁移阈值时,平衡器会尝试在分片之间自动迁移块,并在每个分片中达到相同数量的块。

分片群集的平衡过程对用户和应用程序层完全透明,但在执行过程时可能会对性能产生一些影响。

sharding-migrating.bakedsvg.svg

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

在3.4版中,当平衡器进程处于活动状态时,配置服务器副本集的主服务器通过修改配置数据库中的锁集合中的_id:“balancer”文档来获取“平衡器锁定”。

永远不会发布这种“平衡器锁定”。

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

集群平衡器

平衡器过程负责在每个分片集合的分片中均匀地重新分配分片集合的块。默认情况下,始终启用平衡器进程。

为了解决分片集合的不均匀块分布,平衡器将块从具有更多块的分片迁移到具有更少块的分片。平衡器迁移块,直到分片中的集合均匀分布。有关块迁移的详细信息,请参阅块迁移过程。

版本2.6中已更改:块迁移可能会对磁盘空间产生影响。从MongoDB 2.6开始,源分片默认自动归档迁移的文档。有关详细信息,请参阅moveChunk目录。

块迁移在带宽和工作负载方面带来一些开销,这两者都会影响数据库性能。

平衡器试图通过以下方式将影响降至最低:

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

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

另请参见异步块迁移清除。

仅当碎片与分片集合的最大块数和具有该集合的块数最少的碎片之间的块数之间的差异达到迁移阈值时才开始平衡循环。

您可以暂时禁用平衡器进行维护。有关详细信息,请参阅禁用平衡器。

您还可以限制平衡器运行的窗口,以防止它影响生产流量。有关详细信息,请参阅计划平衡窗口。

注意

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

也可以看看

管理Sharded Cluster Balancer。

从MongoDB 4.0.3开始,如果已为集合定义了区域和区域范围,则分片集合操作可以为空的或不存在的集合执行初始块创建和分发。块的初始创建和分发允许更快地设置分区分片。在初始分配之后,平衡器按照惯例管理块分配。

从群集中添加和删除碎片

将分片添加到群集会产生不平衡,因为新分片没有块。

虽然MongoDB开始立即将数据迁移到新分片,但在群集平衡之前可能需要一些时间。

有关向群集添加分片的说明,请参阅向分组添加分片教程。

从群集中删除分片会产生类似的不平衡,因为驻留在该分片上的块必须在整个群集中重新分配。

虽然MongoDB立即开始耗尽已删除的分片,但在群集平衡之前可能需要一些时间。

在此过程中,请勿关闭与已删除分片关联的服务器。

当您删除具有不均匀块分布的群集中的分片时,平衡器首先从排出分片中删除块,然后平衡剩余的不均匀块分布。

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

块迁移过程

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

balancer进程将moveChunk命令发送到源分片。

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

目标分片构建源所需的任何索引,这些索引在目标上不存在。

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

在块中接收到最终文档后,目标分片会启动同步过程,以确保它对迁移期间发生的迁移文档进行了更改。

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

源分片完成元数据更新后,一旦块上没有打开的游标,源分片将删除其文档副本。

注意

如果平衡器需要从源分片执行其他块迁移,则平衡器可以启动下一个块迁移,而无需等待当前迁移过程完成此删除步骤。请参见异步块迁移清除。

版本2.6中已更改:默认情况下,源分片会自动归档已迁移的文档。有关更多信息,请参阅moveChunk目录。

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

迁移阈值

为了最小化平衡对群集的影响,平衡器仅在分片收集的块的分布达到特定阈值之后才开始平衡。

阈值适用于具有该集合的最多块的分片与具有该集合的最少块的分片之间的块数量的差异。

平衡器具有以下阈值:

块数迁移阈值

少于20 2 20-79 4 80岁及以上 8

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

异步块迁移清理

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

这种排队行为允许分片在群集严重不平衡的情况下更快地卸载块,例如在执行初始数据加载而不预先分割和添加新分片时。

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

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

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

块迁移和复制

版本3.4中已更改。

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

在config.settings集合中:

如果将平衡器的_secondaryThrottle设置设置为写入问题,则在继续下一个文档之前,在块迁移期间移动的每个文档都必须接收所请求的确认。

如果平衡器的_secondaryThrottle设置设置为true,则在块迁移期间移动的每个文档必须在迁移继续进行块中的下一个文档之前从至少一个辅助节点接收确认。这相当于{w:2}的写入问题。

如果未设置_secondaryThrottle设置,则迁移过程不会等待复制到辅助节点,而是继续下一个文档。

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

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

独立于任何_secondaryThrottle设置,块迁移的某些阶段具有以下复制策略:

在使用块的新位置更新配置服务器之前,MongoDB会短暂暂停所有应用程序对源迁移的迁移集合的读取和写入,并在更新后恢复应用程序的读取和写入。块移动要求在将块移动到配置服务器之前和之后,所有写入都由副本集的大多数成员确认。 当传出的块迁移完成并进行清理时,必须将所有写入复制到大多数服务器,然后再进行清理(从其他传出迁移)或新的传入迁移可以继续。 要更新config.settings集合中的_secondaryThrottle设置,请参阅Secondary Throttle示例。

每个要迁移的块的最大文档数

版本3.4.11中已更改。

如果块中的文档数量大于将配置的块大小除以平均文档大小的结果的1.3倍,则MongoDB无法移动块。

db.collection.stats() 包含avgObjSize字段,该字段表示集合中的平均文档大小。

分片大小

默认情况下,随着数据集的增长,MongoDB会尝试使用每个分片上的数据填充所有可用磁盘空间。

要确保群集始终具有处理数据增长的能力,请监视磁盘使用情况以及其他性能指标。

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

参考资料

https://docs.mongodb.com/manual/core/ranged-sharding/