Zones
在分片群集中,您可以根据分片键创建分片数据区域。您可以将每个区域与群集中的一个或多个分片相关联。分片可以与任意数量的区域相关联。在平衡群集中,MongoDB仅将区域覆盖的块迁移到与该区域关联的分片。
可以应用区域的一些常见部署模式如下:
隔离特定分片集上的特定数据子集。
确保最相关的数据驻留在地理上最靠近应用程序服务器的分片上。
根据分片硬件的硬件/性能将数据路由到分片。
下图显示了具有三个分片和两个分区的分片群集。
A区域表示边界下限为1且上限为10的范围.B区域表示边界下限为10,上边界为20的范围.Shards Alpha和Beta具有A区域。 Shard Beta也有B区。
Shard Charlie没有与之相关的区域。群集处于稳定状态,没有任何块违反任何区域。
行为和操作
范围
每个区域涵盖一个集合的一个或多个分片键值范围。区域覆盖的每个范围始终包括其下边界并且不包括其上边界。
区域不能共享范围,也不能具有重叠范围。
为了定义范围,MongoDB提供了updateZoneKeyRange命令和相关的辅助方法sh.updateZoneKeyRange()和sh.addShardTag()。
从MongoDB 4.0.2开始,您可以在unsharded集合或不存在的集合上运行updateZoneKeyRange数据库命令及其帮助程序sh.updateZoneKeyRange()和sh.addTagRange()。
从MongoDB 4.0.2开始,删除集合将删除其关联的区域/标记范围。
初始块分布
版本4.0.3中已更改。
通过在分割空集合或不存在集合之前定义区域和区域范围,分片集合操作为定义的区域范围以及任何其他块创建块以覆盖整个分片键值范围并执行初始化基于区域范围的块分布。这种块的初始创建和分发允许更快地设置分区分片。在初始分发之后,平衡器管理未来的块分布。
有关示例,请参阅为空或非现有集合预定义区域和区域范围。
平衡器
平衡器尝试在群集中的所有分片上均匀分布分片集合的块。
对于标记为要迁移的每个块,平衡器会检查每个可能的目标分片以查找任何已配置的区域。如果块区域落入区域,则平衡器将块迁移到该区域内的分片。不属于区域的块可以存在于群集中的任何分片上,并且可以正常迁移。
在平衡轮次期间,如果平衡器检测到任何块违反给定分片的已配置区域,则平衡器会将这些块迁移到不存在冲突的分片。
将区域与分片或分片相关联并使用分片集合的分片键范围配置区域后,群集可能需要一些时间来迁移分片集合的受影响数据。这取决于块的划分和群集中当前数据的分布。平衡完成后,给定区域中文档的读取和写入仅路由到该区域内的分片或分片。
配置完成后,平衡器将在未来的平衡轮次中考虑区域。
碎片键
在为要覆盖的区域定义新范围时,必须使用分片键中包含的字段。如果使用复合分片键,则范围必须包含分片键的前缀。
例如,给定分片键{a:1,b:2,c:3},创建或更新区域以覆盖b的值需要包括a作为前缀。创建或更新区域以涵盖c的值需要包括a和b作为前缀。
您无法使用分片键中未包含的字段创建区域。例如,如果要使用区域根据地理位置对数据进行分区,则分片键至少需要一个包含地理数据的字段。
为集合选择分片键时,请考虑可能要用于配置分区的字段。分片后,您无法更改分片键。有关选择分片键的注意事项,请参阅选择分片键。
散列碎片键和区域
在散列的分片键上使用区域时,每个区域都会覆盖散列的分片键值。给定分片键{a:1}和下限为1且上限为5的区域alpha,边界表示a的散列值,而不是实际值。因此,无法保证MongoDB将值为1到5的文档路由到区域alpha。
MongoDB将散列碎片键值落在1或5范围内的任何文档路由到区域alpha内的碎片。
通常,覆盖连续范围的散列碎片键值的区域可能表现出意外行为。
可以使用minkey和maxkey创建一个覆盖整个分片键值范围的区域,以保证MongoDB将特定集合的所有数据限制为该区域中的分片或分片。
碎片区边界
区域范围始终包括下边界并且不包括上边界。
参考资料
https://docs.mongodb.com/manual/core/ranged-sharding/