分片集群均衡器
MongoDB 均衡器是一个后台进程,它监视每个分片上的数据量。每个分片集合都有一个分片。当给定分片上的分片集合数据量达到特定迁移阈值时,均衡器会尝试自动在分片之间迁移数据,同时尊重分区。默认情况下,均衡器进程始终启用。
对于分片集群的均衡过程对用户和应用层是完全透明的,尽管在执行过程中可能会有一些性能影响。
均衡器运行在配置服务器副本集(CSRS)的主节点上。
要为单个集合配置集合均衡,请参阅configureCollectionBalancing
。
要管理分片集群均衡器,请参阅管理分片集群均衡器。
均衡器内部
范围迁移在带宽和工作负载方面都会产生一些开销,这些都会影响数据库性能。均衡器通过以下方式尽量减少影响:
将分片限制为在任何给定时间内最多进行一次迁移。具体来说,一个分片不能同时参与多个数据迁移。均衡器一次迁移一个范围。
MongoDB可以并行执行数据迁移,但一个分片一次最多只能参与一个迁移。对于有n个分片分片集群,MongoDB最多可以执行n/2(向下取整)个并行迁移。
另请参阅异步范围迁移清理。
只有在分片集合中数据量最多的分片与数据量最少的分片之间数据量差异达到迁移阈值时才启动平衡轮。
您可以在维护期间暂时禁用均衡器,但长时间禁用均衡器可能会降低集群性能。更多信息,请参阅禁用均衡器。
您还可以限制均衡器运行的时间窗口,以防止其影响生产流量。有关详细信息,请参阅安排平衡窗口。
注意
平衡窗口的指定相对于配置服务器副本集主机的本地时区。
将分片添加到集群中或从集群中删除分片
将分片添加到集群中会创建一个不平衡,因为新的分片没有任何数据。虽然MongoDB立即开始将数据迁移到新的分片,但集群平衡可能需要一些时间。有关将分片添加到集群的说明,请参阅将分片添加到集群教程。
提示
如果您的应用程序符合开始之前的要求,您可以使用reshardCollection
命令将数据重新分配到集群中,包括新的分片。此过程比替代的范围迁移过程快得多。
有关示例,请参阅将数据重新分配到新分片。
从集群中删除分片也会创建类似的平衡,因为驻留在该分片上的数据必须重新分配到整个集群。虽然MongoDB立即开始排空已删除的分片,但集群平衡可能需要一些时间。在此过程中,请不要关闭与已删除分片关联的服务器。
当您从具有不均匀数据块分布的集群中删除分片时,均衡器首先从排空的分片中删除数据块,然后平衡剩余的不均匀数据块分布。
有关安全删除集群中分片的说明,请参阅从集群中删除分片教程。
范围迁移程序
所有范围迁移都使用以下程序
均衡器进程向源分片发送
moveRange
命令。源分片接收到内部
moveRange
命令后开始迁移。在迁移过程中,对范围的作业发送到源分片。源分片负责范围的入站写操作。目标分片构建源分片所需但目标分片上不存在的任何索引。
目标分片开始请求范围内的文档,并开始接收数据的副本。另请参阅 范围迁移和复制。
在收到范围内最后一个文档后,目标分片开始同步过程,以确保它具有迁移过程中发生的迁移文档的更改。
在完全同步后,源分片连接到 配置数据库 并更新集群元数据,以包含范围的新的位置。
在源分片完成元数据更新后,并且在该范围内没有打开的游标后,源分片将删除其文档副本。
注意
如果均衡器需要从源分片执行额外的数据块迁移,均衡器可以开始下一个数据块迁移,而无需等待当前迁移过程完成此删除步骤。请参阅 异步范围迁移清理。
警告
在具有迁移的分片集群中进行辅助读取可能会丢失文档
在分片集群中进行长时间运行的辅助读取可能会在迁移发生时丢失文档。
在删除数据分片进行迁移之前,MongoDB会等待orphanCleanupDelaySecs
参数指定的延迟时间,或者等待涉及该数据分片的正在进行的查询在分片主节点上完成,两者取其长。如果在节点降级为从节点后继续执行的查询最初是在主节点上运行的,则这些查询将被视为最初是在从节点上执行的。也就是说,如果当前主节点上没有针对该数据分片的查询,则服务器只会等待orphanDelayCleanupSecs
。
在从节点上运行的针对数据分片的查询,如果这些查询的执行时间超过了orphanCleanupDelaySecs
,可能会错过一些文档。
迁移阈值
为了最小化平衡对集群的影响,平衡器只有在分片集合的数据分布达到一定的阈值后才开始进行平衡。
如果数据分片(对于该集合)之间的数据差异小于配置的范围大小的三倍,则认为集合是平衡的。对于默认的范围大小128MB
,两个分片必须具有至少384MB
的数据大小差异,才能发生迁移。
异步范围迁移清理
要从一个分片迁移数据,平衡器会一次迁移一个范围的数据。然而,平衡器在开始下一个范围迁移之前不会等待当前迁移的删除阶段完成。有关范围迁移过程和删除阶段的详细信息,请参阅范围迁移。
这种排队行为允许在集群高度不平衡的情况下(例如在没有预分割进行初始数据加载或添加新分片时)更快地卸载数据。
这种行为还会影响 moveRange
命令,使用 moveRange
命令的迁移脚本可能会更快地执行。
在某些情况下,删除阶段可能会持续更长时间。范围迁移被增强以在删除阶段发生故障转移时更具弹性。即使副本集的主节点在此阶段崩溃或重启,也会清理孤儿文档。
_waitForDelete
调度器设置可以改变行为,使得当前迁移的删除阶段阻止下一个数据块迁移的开始。通常,_waitForDelete
用于内部测试目的。有关更多信息,请参阅等待删除。
注意
范围删除是一个资源密集型操作,当集群删除文档时,可能会对缓存和I/O造成重大压力。
如果您计划移动大量数据,例如向集群添加分片或在多个分片上初始分布分片集合时,请考虑重新分片集合。重新分片操作不需要范围清理,这使它们对集群的压力小得多。
有关更多信息,请参阅重新分片集合。
范围迁移和复制
在范围迁移期间,_secondaryThrottle
值确定何时开始迁移范围内的下一个文档。
在 config.settings
集合中
如果平衡器的
_secondaryThrottle
设置为 写关注,则在范围迁移期间移动的每个文档都必须在继续下一个文档之前收到所需的确认。如果未设置
_secondaryThrottle
设置,则迁移过程不会等待复制到辅助节点,而是继续下一个文档。
有关更新平衡器的 _secondaryThrottle
参数的示例,请参阅辅助节点节流。
与任何 _secondaryThrottle
设置无关,范围迁移的某些阶段具有以下复制策略
在将集合迁移到源分片之前,MongoDB会暂时暂停所有对正在迁移的集合的读取和写入操作,以便更新配置服务器的范围位置。更新后,MongoDB会恢复应用程序的读取和写入操作。范围移动要求在将范围移动提交到配置服务器之前和之后,都需要副本集大多数成员确认所有写入。
当出向迁移完成并清理时,在进一步的清理(来自其他出向迁移)或新的入向迁移可以继续之前,所有写入都必须复制到大多数服务器。
要更新_secondaryThrottle
设置在config.settings
集合中,请参阅二级节流以获取示例。
每个迁移范围的最大文档数
默认情况下,如果范围内的文档数量大于配置的范围大小
除以平均文档大小结果的两倍,MongoDB无法移动该范围。如果MongoDB可以移动数据块的一部分并将其大小减少到更低,则平衡器会通过迁移范围来实现。 db.collection.stats()
包括表示集合中平均文档大小的 avgObjSize
字段。
对于太大而无法迁移的数据块:
平衡器设置
attemptToBalanceJumboChunks
允许平衡器迁移太大而无法移动的数据块,只要这些数据块未被标记为巨型
。有关详细信息,请参阅超出大小限制的范围平衡。当执行
moveRange
和moveChunk
命令时,可以指定 forceJumbo 选项,允许迁移太大而无法移动的分区。这些分区可能被标记为 大分区。
范围删除性能优化
您可以使用 rangeDeleterBatchSize
和 rangeDeleterBatchDelayMS
来调整范围删除的性能影响。
例如
要限制每批删除的文档数量,可以将
rangeDeleterBatchSize
设置为较小的值,例如32
。要增加批量删除之间的额外延迟,可以将
rangeDeleterBatchDelayMS
设置在当前的默认值20
毫秒之上。
注意
如果目标集合有正在进行的读取操作或打开的光标,则范围删除过程可能无法进行。
更改流和孤儿文档
分片大小
默认情况下,随着数据集的增长,MongoDB会尝试在每个分片上用数据填充所有可用磁盘空间。为确保集群始终具有处理数据增长的能力,请监视磁盘使用情况以及其他性能指标。
有关设置分片最大大小的说明,请参阅更改给定分片的最大存储大小教程。
数据块大小和平衡
有关chunkSize
的介绍,请参阅在分片集群中修改数据块大小教程。
下表描述了在不同MongoDB版本中,chunkSize
如何影响碎片整理和平衡器操作。
MongoDB 版本 | 描述 |
---|---|
MongoDB 6.0 及更高版本 | 当两个分片之间共享的集合数据与配置的 例如,如果 |
MongoDB 6.0 之前 | 当数据块的大小超过 chunkSize 时,数据块将被分割。 |
在数据块移动、分割或合并后,由配置服务器提交数据块操作后,将更新分片元数据。未参与数据块操作的分片也将更新为新元数据。
分片元数据更新的时间与路由表的大小成正比。在更新分片元数据时,集合上的 CRUD 操作将暂时被阻止,而较小的路由表意味着更短的 CRUD 操作延迟。
对集合进行碎片整理可以减少数据块的数量和更新数据块元数据所需的时间。
为了减少系统负载,配置均衡器仅在特定时间运行,使用分片均衡窗口。碎片整理将在均衡窗口时间期间运行。
您可以使用chunkDefragmentationThrottlingMS
参数来限制均衡器运行的拆分和合并命令的速率。
您可以在任何时间启动和停止碎片整理。
您还可以设置一个分片区域。分片区域基于分片键,您可以将每个区域与集群中的一个或多个分片关联。
从 MongoDB 6.0 开始,当数据块必须迁移时,分片集群才会拆分数据块。这意味着数据块的大小可能超过chunkSize
。较大的数据块减少了分片上的数据块数量,并提高了性能,因为更新分片元数据所需的时间减少了。例如,即使您已将chunkSize
设置为 256 MB,您可能会在一个分片上看到 1 TB 的数据块。
chunkSize
影响以下内容
平衡器在单个数据块迁移操作中尝试在两个分片之间迁移的数据量上限。
碎片整理期间迁移的数据量。
有关碎片整理分片集合的详细信息,请参阅碎片整理分片集合。