MongoDB的平衡器是一个后台进程监视器的数目 的块上的每个分片。当给定分片上的块数达到特定的迁移阈值时,平衡器将尝试自动在分片之间迁移块,并使每个分片上的块数相等。
分片群集的平衡过程对于用户和应用程序层是完全透明的,尽管在进行过程中可能会对性能产生一些影响。
从MongoDB 3.4开始,平衡器在配置服务器副本集(CSRS)的主数据库上运行:
_id: "balancer"
locks
该平衡器进程负责再分配分片收集的大块碎片对每个分片收集平均分配。默认情况下,平衡器进程始终处于启用状态。
为了解决分片集合的不均匀分块分布,平衡器将分块从具有更多分块的分块迁移到具有更少分块数的分块。平衡器将迁移块,直到整个碎片中的集合的块均匀分布为止。有关块迁移的详细信息,请参见块迁移过程。
块迁移可能会影响磁盘空间,因为默认情况下,源分片会自动存档迁移的文档。有关详细信息,请参见moveChunk目录。
块迁移会带来一些带宽和工作负载方面的开销,这两者都会影响数据库性能。[1]所述的 平衡器的尝试,以尽量减少由冲击:
在任何给定时间将一个分片限制为最多只能进行一次迁移;即,一个分片不能同时参与多个块的迁移。要从一个分片迁移多个块,平衡器一次迁移一个块。
在版本3.4中进行了更改:从MongoDB 3.4开始,MongoDB可以执行并行块迁移。遵守分片每次最多只能参与一次迁移的限制,对于具有n个分 片的分片集群,MongoDB最多可以执行n / 2(向下舍入)的同时块迁移。
另请参见“ 异步块迁移清除”。
仅当分片集合中具有最大块数的分片与该集合中具有最小块数的分片之间的块数差达到迁移阈值时,才开始平衡。
您可以暂时禁用平衡器进行维护。有关详细信息,请参见 禁用平衡器。
您还可以限制平衡器运行的窗口,以防止其影响生产流量。有关详细信息,请参见安排平衡窗口。
注意
平衡窗口的规范是相对于配置服务器副本集主数据库的本地时区的。
也可以看看
[1] | 从MongoDB 4.0.3开始,如果为集合定义了区域和区域范围,则分片收集操作可以为空或不存在的集合执行初始块创建和分配。块的初始创建和分发允许更快地设置分区分片。在初始分配之后,平衡器将按常规管理前进的块分配。 |
将分片添加到群集会造成不平衡,因为新分片没有任何块。当MongoDB立即开始将数据迁移到新的分片时,群集平衡可能需要一些时间。有关将分片添加到集群的说明,请参见将分片 添加到集群教程。
从集群中删除一个分片也会造成类似的不平衡,因为必须重新分配该分片上的分块。当MongoDB立即开始耗尽已删除的分片时,群集平衡可能需要一些时间。在此过程中,请勿关闭与已删除的分片关联的服务器。
当您在块分布不均匀的集群中删除一个分片时,平衡器首先从排水分片中删除这些块,然后平衡其余的不均匀块分布。
请参阅从现有分片集群中删除分片教程,以获取有关从集群中安全删除分片的说明。
所有块迁移均使用以下过程:
平衡器进程将moveChunk
命令发送到源分片。
源使用内部moveChunk
命令开始移动。在迁移过程中,对块的操作将路由到源分片。源碎片负责该块的传入写操作。
目标分片将构建源中所需的,目标上不存在的所有索引。
目标分片开始请求块中的文档,并开始接收数据的副本。另请参见 块迁移和复制。
在接收到块中的最终文档之后,目标分片将启动同步过程,以确保它具有对迁移期间发生的已迁移文档的更改。
完全同步后,源分片将连接到 配置数据库,并使用该块的新位置来更新集群元数据。
源分片完成元数据的更新之后,并且一旦块上没有打开的游标,则源分片将删除其文档副本。
注意
如果平衡器需要从源碎片执行其他块迁移,则平衡器可以开始下一个块迁移,而无需等待当前的迁移过程完成此删除步骤。请参阅异步块迁移清除。
也可以看看
迁移过程可确保一致性,并在平衡期间最大程度地利用块。
为了最大程度地减少平衡对集群的影响, 平衡器仅在分片集合的块分配达到某些阈值之后才开始平衡。阈值适用于数量的差异块 最块的收集和使用大块该集合最少的碎片碎片之间。平衡器具有以下阈值:
块数 | 迁移阈值 |
---|---|
少于20 | 2 |
20-79 | 4 |
80以上 | 8 |
当该集合的任何两个分片上的块数之差小于2或块迁移失败时,平衡器将停止在目标集合上运行。
要从一个分片迁移多个块,平衡器一次迁移一个块。但是,平衡器在开始下一个块迁移之前不会等待当前迁移的删除阶段完成。有关块迁移过程和删除阶段,请参见块迁移。
这种排队行为使分片在集群严重不平衡的情况下可以更快地卸载块,例如在不进行预拆分的情况下执行初始数据加载以及添加新分片时。
此行为也会影响moveChunk
命令,并且使用该moveChunk
命令的迁移脚本可能会更快地进行。
在某些情况下,删除阶段可能会持续更长时间。如果多个删除阶段处于排队状态,但尚未完成,则副本集的主数据库崩溃可能会使来自多个迁移的数据孤立。
的_waitForDelete
,可作为平衡器的设置,以及该moveChunk
命令,可以改变行为,以便当前迁移块的删除阶段的一个块迁移的开始。在_waitForDelete
通常用于内部测试的目的。有关更多信息,请参见
等待删除。
在版本3.4中更改。
在块迁移期间,该_secondaryThrottle
值确定何时对块中的下一个文档进行迁移。
在config.settings
集合中:
_secondaryThrottle
平衡器的设置设置为写关注点,则在进行下一个文档之前,在块迁移期间移动的每个文档都必须收到请求的确认。_secondaryThrottle
平衡器的设置设置为
true
,则在迁移继续进行块中的下一个文档之前,在块迁移期间移动的每个文档都必须至少从一个辅助节点收到确认。这等效于的写关注。{ w: 2 }
_secondaryThrottle
设置,迁移过程将不等待复制到辅助数据库,而是继续下一个文档。要更新_secondaryThrottle
平衡器的参数,请参阅
辅助油门示例。
与任何_secondaryThrottle
设置无关,大块迁移的某些阶段具有以下复制策略:
要更新集合中的_secondaryThrottle
设置
config.settings
,请参阅“
辅助油门 ”作为示例。
在版本3.4.11中进行了更改。
如果块中的文档数大于配置的块大小除以平均文档大小的结果的1.3倍,则MongoDB无法移动块
。
db.collection.stats()
包括avgObjSize
字段,该字段代表集合中的平均文档大小。
默认情况下,随着数据集的增长,MongoDB会尝试使用每个分片上的数据填充所有可用磁盘空间。为确保群集始终具有处理数据增长的能力,请监视磁盘使用情况以及其他性能指标。
有关设置分片最大大小的说明,请参见“ 更改给定分片的最大存储大小”教程。