文档菜单
文档首页
/
MongoDB 手册
/

分片集群均衡器

本页内容

  • 均衡器内部机制
  • 范围迁移过程
  • 分片大小
  • 数据块大小和均衡

MongoDB 均衡器是一个后台进程,它监视每个分片上的数据量。每个分片集合都有一个分片。当给定分片上的分片集合数据量达到特定迁移阈值时,均衡器会尝试自动在分片之间迁移数据,同时尊重分区。默认情况下,均衡器进程始终启用。

对于分片集群的均衡过程对用户和应用层是完全透明的,尽管在执行过程中可能会有一些性能影响。

Diagram of a collection distributed across three shards. For this collection, the difference in the number of chunks between the shards reaches the *migration thresholds* (in this case, 2) and triggers migration.

均衡器运行在配置服务器副本集(CSRS)的主节点上。

要为单个集合配置集合均衡,请参阅configureCollectionBalancing

要管理分片集群均衡器,请参阅管理分片集群均衡器。

范围迁移在带宽和工作负载方面都会产生一些开销,这些都会影响数据库性能。均衡器通过以下方式尽量减少影响:

  • 将分片限制为在任何给定时间内最多进行一次迁移。具体来说,一个分片不能同时参与多个数据迁移。均衡器一次迁移一个范围。

    MongoDB可以并行执行数据迁移,但一个分片一次最多只能参与一个迁移。对于有n个分片分片集群,MongoDB最多可以执行n/2(向下取整)个并行迁移。

    另请参阅异步范围迁移清理。

  • 只有在分片集合中数据量最多的分片与数据量最少的分片之间数据量差异达到迁移阈值时才启动平衡轮。

您可以在维护期间暂时禁用均衡器,但长时间禁用均衡器可能会降低集群性能。更多信息,请参阅禁用均衡器。

您还可以限制均衡器运行的时间窗口,以防止其影响生产流量。有关详细信息,请参阅安排平衡窗口

注意

平衡窗口的指定相对于配置服务器副本集主机的本地时区。

提示

另请参阅

将分片添加到集群中会创建一个不平衡,因为新的分片没有任何数据。虽然MongoDB立即开始将数据迁移到新的分片,但集群平衡可能需要一些时间。有关将分片添加到集群的说明,请参阅将分片添加到集群教程。

提示

如果您的应用程序符合开始之前的要求,您可以使用reshardCollection命令将数据重新分配到集群中,包括新的分片。此过程比替代的范围迁移过程快得多。

有关示例,请参阅将数据重新分配到新分片

从集群中删除分片也会创建类似的平衡,因为驻留在该分片上的数据必须重新分配到整个集群。虽然MongoDB立即开始排空已删除的分片,但集群平衡可能需要一些时间。在此过程中,请不要关闭与已删除分片关联的服务器。

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

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

所有范围迁移都使用以下程序

  1. 均衡器进程向源分片发送 moveRange 命令。

  2. 源分片接收到内部 moveRange 命令后开始迁移。在迁移过程中,对范围的作业发送到源分片。源分片负责范围的入站写操作。

  3. 目标分片构建源分片所需但目标分片上不存在的任何索引。

  4. 目标分片开始请求范围内的文档,并开始接收数据的副本。另请参阅 范围迁移和复制。

  5. 在收到范围内最后一个文档后,目标分片开始同步过程,以确保它具有迁移过程中发生的迁移文档的更改。

  6. 在完全同步后,源分片连接到 配置数据库 并更新集群元数据,以包含范围的新的位置。

  7. 在源分片完成元数据更新后,并且在该范围内没有打开的游标后,源分片将删除其文档副本。

    注意

    如果均衡器需要从源分片执行额外的数据块迁移,均衡器可以开始下一个数据块迁移,而无需等待当前迁移过程完成此删除步骤。请参阅 异步范围迁移清理。

警告

在具有迁移的分片集群中进行辅助读取可能会丢失文档

在分片集群中进行长时间运行的辅助读取可能会在迁移发生时丢失文档。

在删除数据分片进行迁移之前,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允许平衡器迁移太大而无法移动的数据块,只要这些数据块未被标记为巨型。有关详细信息,请参阅超出大小限制的范围平衡

    当执行 moveRangemoveChunk 命令时,可以指定 forceJumbo 选项,允许迁移太大而无法移动的分区。这些分区可能被标记为 大分区。

您可以使用 rangeDeleterBatchSizerangeDeleterBatchDelayMS 来调整范围删除的性能影响。

例如

  • 要限制每批删除的文档数量,可以将 rangeDeleterBatchSize 设置为较小的值,例如 32

  • 要增加批量删除之间的额外延迟,可以将 rangeDeleterBatchDelayMS 设置在当前的默认值 20 毫秒之上。

注意

如果目标集合有正在进行的读取操作或打开的光标,则范围删除过程可能无法进行。

从MongoDB 5.3版本开始,在范围迁移过程中,不会为变更流事件生成孤立文档更新的事件。

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

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

有关chunkSize的介绍,请参阅在分片集群中修改数据块大小教程。

下表描述了在不同MongoDB版本中,chunkSize如何影响碎片整理和平衡器操作。

MongoDB 版本
描述
MongoDB 6.0 及更高版本

当两个分片之间共享的集合数据与配置的chunkSize设置相差三倍或更多时,平衡器会在分片之间迁移数据块。

例如,如果chunkSize为128 MB,且集合数据相差384 MB或更多,平衡器将在分片之间迁移数据块。

MongoDB 6.0 之前
当数据块的大小超过chunkSize时,数据块将被分割。

在数据块移动、分割或合并后,由配置服务器提交数据块操作后,将更新分片元数据。未参与数据块操作的分片也将更新为新元数据。

分片元数据更新的时间与路由表的大小成正比。在更新分片元数据时,集合上的 CRUD 操作将暂时被阻止,而较小的路由表意味着更短的 CRUD 操作延迟。

对集合进行碎片整理可以减少数据块的数量和更新数据块元数据所需的时间。

为了减少系统负载,配置均衡器仅在特定时间运行,使用分片均衡窗口。碎片整理将在均衡窗口时间期间运行。

您可以使用chunkDefragmentationThrottlingMS参数来限制均衡器运行的拆分和合并命令的速率。

您可以在任何时间启动和停止碎片整理。

您还可以设置一个分片区域。分片区域基于分片键,您可以将每个区域与集群中的一个或多个分片关联。

从 MongoDB 6.0 开始,当数据块必须迁移时,分片集群才会拆分数据块。这意味着数据块的大小可能超过chunkSize。较大的数据块减少了分片上的数据块数量,并提高了性能,因为更新分片元数据所需的时间减少了。例如,即使您已将chunkSize设置为 256 MB,您可能会在一个分片上看到 1 TB 的数据块。

chunkSize影响以下内容

  • 平衡器在单个数据块迁移操作中尝试在两个分片之间迁移的数据量上限。

  • 碎片整理期间迁移的数据量。

有关碎片整理分片集合的详细信息,请参阅碎片整理分片集合。

返回

停止移动集合