Data Partitioning with Chunks

MongoDB Atlas使用最佳实践实现分片,允许您通过GUI扩展群集。

配置服务器和查询路由器的部署和管理是完全自动化的。 从这里开始吧。

MongoDB使用与集合关联的分片键将数据分区为块。

块由分片数据的子集组成。

每个块都具有基于分片键的包含较低且独占的较高范围。

sharding-range-based.bakedsvg.svg

mongos路由根据分片键值写入适当的块。

MongoDB在超出配置的块大小时会拆分块。

插入和更新都可以触发块拆分。

块可以表示的最小范围是单个唯一的分片键值。

仅包含具有单个分片键值的文档的块无法拆分。

初始块

人口稠密的集合

分片操作创建初始块以覆盖整个分片键值范围。创建的块数取决于配置的块大小。

在初始块创建之后,平衡器会根据需要在分片中迁移这些初始块,并管理未来的块分布。

空集合

如果为空或不存在的集合定义区域和区域范围(从MongoDB 4.0.3开始可用):

分片操作为定义的区域范围以及任何其他块创建空块,以覆盖整个分片键值范围,并根据区域范围执行初始块分布。这种块的初始创建和分发允许更快地设置分区分片。 在初始分发之后,平衡器管理未来的块分布。

如果没有为空集合或不存在集合定义区域和区域范围:

  • 对于散列分片:

分片操作创建空块以覆盖整个分片键值范围并执行初始块分发。默认情况下,该操作会为每个分片创建2个块,并在群集中进行迁移。您可以使用numInitialChunks选项指定不同数量的初始块。这种块的初始创建和分发允许更快地设置分片。

在初始分发之后,平衡器管理未来的块分布。

  • 对于远程分片:

分片操作会创建一个空的块,以覆盖整个分片键值范围。

在初始块创建之后,平衡器在适当的情况下跨分片迁移初始块,以及管理未来的块分布。

块大小

MongoDB中的默认块大小为64兆字节。您可以增加或减少块大小。考虑更改默认块大小的含义:

较小的块导致更均匀的数据分布,但代价是更频繁的迁移。这会在查询路由(mongos)层创建费用。

较大的块导致较少的迁移。从网络角度和查询路由层的内部开销来看,这都是更有效的。但是,这些效率是以可能不均衡的数据分布为代价的。 块大小会影响每个要迁移的块的最大文档数。

分片现有集合时,块大小会影响最大集合大小。分片后,块大小不会限制集合大小。

对于许多部署,避免频繁和潜在的虚假迁移是有意义的,但代价是分布不均匀的数据集。

限制

更改块大小会影响块分块但其效果有一些限制。

自动拆分仅在插入或更新期间发生。如果降低块大小,则所有块可能需要一段时间才能拆分为新大小。

分裂不能“撤消”。如果增加块大小,则现有块必须通过插入或更新来增长,直到它们达到新大小。

块迁移

MongoDB在分片群集中迁移块,以在分片中均匀分布分片集合的块。

迁移可能是:

手册。 仅在有限的情况下使用手动迁移,例如在批量插入期间分发数据。 有关更多详细信息,请参阅手动迁移块。 自动。 当分片中分片集合的块分布不均匀时,平衡器进程会自动迁移块。 有关详细信息,请参阅迁移阈值。 有关分片群集平衡器的详细信息,请参阅Sharded Cluster Balancer。

平衡

平衡器是管理块迁移的后台进程。

如果最大和最小分片之间的块数差异超过迁移阈值,则平衡器开始在群集中迁移块以确保数据的均匀分布。

sharding-migrating.bakedsvg.svg

您可以管理平衡器的某些方面。

平衡器还会考虑作为在分片群集中配置区域的一部分而创建的任何区域。

有关平衡器的更多信息,请参见Sharded Cluster Balancer。

不可分割的块

在某些情况下,块可能会超出指定的块大小但不能进行拆分。最常见的情况是块表示单个分片键值。由于块不能分割,它继续增长超过块大小,成为一个巨大的块。这些巨型块在它们继续增长时可能成为性能瓶颈,特别是如果分片键值以高频率出现时。

添加新数据或新分片可能导致群集内的数据分布不平衡。特定分片可能比另一个分片获取更多块,或者块的大小可能超过配置的最大块大小。

MongoDB使用两个进程确保平衡集群:块拆分和平衡器。

moveChunk目录

在MongoDB 2.6和MongoDB 3.0中,默认情况下启用了sharding.archiveMovedChunks。

默认情况下,所有其他MongoDB版本都禁用此功能。

启用sharding.archiveMovedChunks后,源分片会将迁移的块中的文档归档到storage.dbPath中moveChunk目录下以collection名称空间命名的目录中。

如果在迁移期间发生某些错误,这些文件可能有助于恢复迁移期间受影响的文档。

迁移成功完成后,无需从这些文件中恢复文档,您可以安全地删除这些文件。或者,如果您有可用于恢复的数据库的现有备份,则也可以在迁移后删除这些文件。

要确定是否所有迁移都已完成,请在连接到mongos实例时运行sh.isBalancerRunning()。

参考资料

https://docs.mongodb.com/manual/core/sharding-data-partitioning/