分片集群负载均衡器
MongoDB负载均衡器是一个背景进程,用于监控每个分片上的数据段分片。 当给定分片上的数据段分片达到特定的迁移阈值时,负载均衡器会尝试在分片之间自动迁移数据段,并达到每个分片的数据段数量分片。
分片集群的均衡过程对用户和应用程序层是完全透明的,不过在执行过程中可能会对性能产生一些影响。
负载均衡器在配置服务器副本集 (CSRS) 的主节点上运行。
集群负载均衡器
负载均衡器进程负责在每个分分片的集合的分片之间均匀地重新分配分分片的集合的数据段。 默认,负载均衡器进程始终处于启用状态。
为了解决分片集合数据段分布不均的问题,负载均衡器会将数据段从数据段较多的分片迁移到数据段较少的分片。 负载均衡器会迁移数据段,直到集合的数据段均匀分布在各分片上。 有关数据段迁移的详细信息,请参阅数据段迁移过程。
数据段迁移可能会对磁盘空间产生影响,因为源分片默认会自动存档迁移的文档。 有关详细信息,请参阅 moveChunk
目录。
数据段迁移会带来一定的带宽和工作负载开销,而这两者都会影响数据库性能。 [ 1 ]负载均衡器尝试通过以下方式尽量减少影响:
在任何给定时间将分片限制为最多一次迁移;即一个分片不能同时参与多个数据段迁移。 要从分片迁移多个数据段,负载均衡器会一次迁移一个数据段。
在版本3.4中进行了更改: 从MongoDB 3.4开始, MongoDB可以执行并行数据数据块迁移。 迁移的限制,对于一个有n 个分片的分片分片集群, MongoDB最多可以执行n/ 2 (四舍五入)个并行数据数据块迁移。
另请参阅异步数据段迁移清理。
仅当分片集合中数据段数量最多的分片与该集合中数据段数量最少的分片之间的数据段数量差值达到 迁移阈值 时, 才 开始均衡轮次。
您可以暂时禁用负载均衡器以进行维护,但长时间禁用负载均衡器可能会降低集群性能。 有关更多信息,请参阅禁用负载均衡器。
您还可以限制负载均衡器的运行时间窗口,以防止它影响生产流量。有关详细信息,请参阅安排均衡窗口。
注意
均衡窗口是相对于配置服务器副本集主节点的本地时区而指定的。
[1] | 如果已为集合定义区域和区域范围,则分分片集合操作可以为空或不存在的集合执行初始数据数据块创建和分配。 数据段的初始创建和数据块可以更快地设置分区分片。 初始分配后,负载均衡器将数据块管理未来的数据段分配。 MongoDB支持对复合哈希索引上的集合进行分片。 使用复合哈希分片键分片键对空集合或不存在的集合进行分片时,需要满足其他应用, MongoDB才能执行初始数据数据块创建和分发。有关示例,请参阅为空集合或不存在的集合预定义区域和区域范围。 |
在集群中添加和删除分片
向集群添加分片会造成不平衡,因为新分分片没有数据段。 虽然MongoDB会立即开始将数据迁移到新分片,但集群可能需要一些时间才能达到平衡。 有关向集群添加分片的说明,请分片向集群添加分片教程。
从集群中删除分片也会造成类似的不平衡,因为驻留在该分片上的数据段必须在整个集群中重新分布。 虽然 MongoDB 会立即开始清空已删除的分片,但集群可能需要一些时间才能达到平衡。 在此过程中,请勿关闭与已删除分片关联的服务器。
当您从集群中删除数据段分布不均匀的分片时,负载均衡器首先从要清空的分片中删除数据段,然后均衡剩余的不均匀数据段分布。
有关从集群中安全删除分片片的说明,请参阅“从现有分片集群中删除分片”教程。
数据段迁移过程
所有数据块迁移都使用以下过程:
负载均衡器进程将
moveChunk
命令发送到源分片。源使用内部
moveChunk
命令启动移动。 在迁移过程中,对数据段的操作会路由到源分片。 源分片负责传入的数据段写入操作。目标分片会生成源所需要但在目标上不存在的任何索引。
目标分片开始请求数据段中的文档并开始接收数据的副本。 另请参阅数据段迁移和复制。
在接收到数据段中的最终文档后,目标分片会启动同步进程,以确保它拥有迁移过程中对迁移文档所做的更改。
完全同步后,源分片会连接到配置数据库,并使用数据段的新位置更新集群元数据。
源分片完成元数据更新后,一旦该数据段上没有打开的游标,源分片就会删除其文档副本。
注意
如果负载均衡器需要从源分片执行额外的数据数据块迁移,则分片负载均衡器可以开始下一个数据数据块迁移,而无需等待当前迁移进程完成此删除步骤。 请参阅异步数据段迁移清理。
迁移过程可确保一致性,并在均衡期间最大限度地提高数据段的可用性。
迁移阈值
为了最大限度地减少负载均衡对集群的影响,负载均衡器仅在分片集合的数据分布达到导致集群不均衡的迁移阈值后才开始进行负载均衡。 当负载最重的分片上的数据段数量超过每个分片的最佳数据段数量超过1数据段时,集合将不均衡,负载均衡器将启动数据段迁移。 每个分片的最佳数据段数是分片集合中的数据段总数除以分片数量,四舍五入到最接近的整数。 如果区域存在,MongoDB 会按区域计算最佳数据段数。
例如,如果用户将一个新分片添加到由10个分片组成的集合中,每个分片有20个数据段,则负载均衡器不会迁移任何数据。 每个分片上的最佳数据段数量是200除以11或18.18 ,MongoDB 将四舍五入为19 。 由于19和20之间的差值为1 ,因此集群处于均衡状态,负载均衡器不会将任何数据段迁移到新分片。
异步数据段迁移清理
要从分片迁移多个数据段,负载均衡器会一次迁移一个数据段。 但是,负载均衡器不会等待当前迁移的删除阶段完成就开始下一个数据段迁移。 有关数据段迁移过程和删除阶段,请参阅数据段迁移。
这种排队行为允许分片在集群严重失衡的情况下更快地卸载数据段,例如在不进行预分割的情况下执行初始数据加载时以及添加新分片时。
此行为还会影响 moveChunk
命令,使用 moveChunk
命令的迁移脚本可能会执行得更快。
在某些情况下,删除阶段可能会持续更长时间。 从MongoDB 4.4开始,数据数据块迁移得到增强,在删除阶段事件故障转移时更具弹性。 即使副本集的主节点 (primary node in the replica set)节点在此阶段崩溃或重新启动,孤立文档也会被清除。
_waitForDelete
可用作负载均衡器和moveChunk
命令的设置,可以更改行为,以便当前迁移的删除阶段阻止下一个数据段迁移开始。 _waitForDelete
通常用于内部测试目的。 有关更多信息,请参阅等待删除。
注意
范围删除是一项资源密集型操作,当集群删除文档时,可能会导致严重的缓存和 I/O 压力。
如果计划移动大量数据,例如将分片添加到集群时或将分分片的集合初始分发到多个分片期间,请考虑对集合进行重新分片。重新分片操作不需要范围清理,因此对集群的压力要小得多。
数据段迁移和复制
已在 3.4 版本中更改。
在数据块迁移过程中,_secondaryThrottle
值决定何时继续迁移数据块内的下一个文档。
在 config.settings
集合中:
如果将负载均衡器的
_secondaryThrottle
设置为写关注,则在范围迁移期间,每个移动的文档都必须收到请求的确认,才能继续处理下一个文档。如果未进行
_secondaryThrottle
设置,迁移过程不会等待复制到从节点,而是继续处理下一个文档。
要更新负载均衡器的 _secondaryThrottle
参数,请参阅辅助限制示例。
数据段迁移的某些阶段具有以下复制策略,与任何_secondaryThrottle
设置无关:
在使用数据段的新位置更新配置服务器之前, MongoDB在源分片上短暂暂停对正在迁移的集合的所有应用程序读取和数据块,并在更新后恢复应用程序的读取和写入。 在将数据数据块移动提交到配置服务器之前和之后,数据数据块移动要求副本集的大多数成员确认所有写入。
当数据块迁移完成并进行清理时,必须将所有写入复制到大多数服务器,然后才能继续进行进一步的清理(从其他传出迁移)或新的传入迁移。
要更新 config.settings
集合的 _secondaryThrottle
设置,请参阅辅助限制示例。
要迁移的每个数据块的最大文档数
默认情况下,如果数据段中的文档数量大于1.3倍(配置的数据段大小除以平均文档大小所得结果),则 MongoDB 无法移动该数据段。 db.collection.stats()
包括avgObjSize
字段,该字段表示集合中文档的平均大小。
对于太大而无法迁移的数据段,从 MongoDB 4.4开始:
新的负载均衡器设置
attemptToBalanceJumboChunks
允许负载均衡器迁移太大而无法移动的数据段,只要这些数据段未标记为jumbo 。 有关详细信息,请参阅平衡超过大小限制的数据段。moveChunk
命令可以指定一个新选项 forceJumbo,以便迁移过大而无法移动的数据块。这些数据块可能会也可能不会标记为 jumbo。
范围删除性能调整
您可以使用rangeDeleterBatchSize
和rangeDeleterBatchDelayMS
参数调整范围删除对性能的影响。 例如:
要限制每批删除文档的数量,您可以将
rangeDeleterBatchSize
设置为较小的值,如32
。要在批量删除之间添加额外的延迟,您可以将
rangeDeleterBatchDelayMS
设置为高于当前默认值(20
毫秒)。
注意
如果正在对要删除的集合执行读取操作,或者在该集合上具有打开的游标,则可能无法继续执行范围删除过程。
分片大小
默认情况下,随着数据集增长,MongoDB 会尝试用每个分片的数据填充所有可用的磁盘空间。要确保集群始终有能力处理数据增长,请监控磁盘使用情况以及其他性能指标。
有关设置分片最大大小的说明,请参阅更改给定分片的最大存储大小教程。