使用块进行数据分区

在本页面

MongoDB 使用与集合关联的shard key将数据划分为chunkschunk由分片数据的子集组成。每个块都有基于shard key的包含性下限和排除性上限范围。

分片键值空间细分为较小范围或块的图。

mongos路由根据shard key值写入适当的块。当 MongoDB 超出配置的chunk size时,MongoDB 将对其进行拆分。插入和更新都可以触发块拆分。

块可以代表的最小范围是单个唯一的分片键值。仅包含具有单个分片键值的文档的块不能为split

Chunk Size

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

  • 小块数据导致更均匀的数据分发,但代价是迁移频率更高。这在查询路由(mongos)层产生了费用。

  • 大块导致更少的迁移。从网络角度在查询路由层的内部开销方面来说,这都是更有效的。但是,这些效率是以潜在的数据分布不均为代价的。

  • 块大小会影响每块要迁移的最大文档数

  • 分片existing collection时,块大小会影响最大集合大小。分片后,块大小不限制集合大小。

对于许多部署来说,避免频繁且可能是虚 Pseudo 迁移是有道理的,但要付出的代价是分配的数据集分布得不太均匀。

Limitations

更改块大小会影响块分割的时间,但对其效果有一些限制。

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

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

Chunk Splits

拆分是防止块增长太大的过程。当某个块的大小超过指定的块大小时,或者如果该块中的文档数超过Maximum Number of Documents Per Chunk to Migrate,MongoDB 将根据该块代表的分片键值拆分该块。必要时可以将一个大块拆分为多个大块。插入和更新可能会触发拆分。拆分是有效的元数据更改。要创建拆分,MongoDB 不会*迁移任何数据或影响分片。

带有超过默认默认块大小 64 MB 的块的分片图,并触发将该块拆分为两个块。

分割可能会导致碎片中各个集合的块分布不均匀。在这种情况下,平衡器会在各个分片之间重新分配块。有关在各个分片之间平衡块的更多详细信息,请参见Cluster Balancer

Chunk Migration

MongoDB 迁移sharded cluster中的块,以在各个分片之间平均分配分片集合的各块。迁移可能是:

  • 手册。仅在有限的情况下使用手动迁移,例如在批量插入过程中分发数据。有关更多详细信息,请参见手动迁移块

  • 自动。当分片集合的数据块在各个分片之间分布不均时,balancer进程会自动迁移数据块。有关更多详细信息,请参见Migration Thresholds

有关分片群集balancer的更多信息,请参见分片集群平衡器

Balancing

balancer是 Management 块迁移的后台进程。如果最大和最小碎片之间的块数差异超过migration thresholds,那么平衡器将开始在整个群集中迁移块,以确保数据的均匀分布。

分布在三个碎片上的集合图。对于此集合,分片之间的块数量差异达到迁移阈值(在这种情况下为 2)并触发迁移。

您可以manage平衡器的某些方面。平衡器还考虑在分片群集中配置zones时创建的任何zones

有关balancer的更多信息,请参见分片集群平衡器

Indivisible Chunks

在某些情况下,块可以增长到指定的块大小之外,但不能经历split。最常见的情况是块代表单个分片键值。由于块无法拆分,因此它将 continue 增长,超出块大小,成为巨型块。随着它们不断增长,这些巨型块可能会成为性能瓶颈,特别是如果分片键值出现在高frequency的情况下。

moveChunk directory

在 MongoDB 2.6 和 MongoDB 3.0 中,默认情况下启用sharding.archiveMovedChunks。默认情况下,所有其他 MongoDB 版本均禁用此功能。启用sharding.archiveMovedChunks后,源分片会将文档中的迁移块中的文档存档在以storage.dbPathmoveChunk目录下的集合命名空间命名的目录中。

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

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

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