Comment on page
哈希分片
Diagram of the hashed based segmentation.
哈希分片以减少定向操作和增加广播操作作为代价,分片集群内的数据分布更加均衡。在哈希之后,拥有比较“接近”的片键的文档将不太可能会分布在相同的数据库或者分片上。mongos更有可能执行广播操作来完成一个给定的范围查询。相对的,mongos可以将等值匹配的查询直接定位到单个分片上。
注意:当使用哈希索引来解析查询时,MongoDB会自动计算哈希值。应用程序不需要计算哈希。警告MongoDB哈希索引在哈希计算之前会将浮点数截断为64位整数。 例如,哈希索引会将为具有2.3
、2.2
和2.9
的值的字段存储为相同的值。 为了避免冲突,请勿对不能可靠地转换为64位整数(然后再返回到浮点)的浮点数使用哈希索引。 MongoDB哈希索引不支持大于2^53的浮点值。
从4.0版开始,mongo shell提供了 convertShardKeyToHashed() 方法。 此方法使用与哈希索引相同的哈希函数,可用于查看键的哈希值。 |
给定一个使用单调递增的值
X
作为片键的集合,使用范围分片会导致插入数据的分布类似于下面这样:Diagram of poor shard key distribution due to monotonically increasing or decreasing shard key
由于
X
的值始终在增加,因此具有maxKey
(上限)的数据块将接收大多数传入的写操作。 这将插入操作限制在只能定向到包含此块的单个分片,从而减少或消除了分片集群中分布式写入的优势。通过在
X
上使用哈希索引,插入的分布将类似于下面这样:Diagram of hashed shard key distribution
由于现在数据分布更加均匀,因此可以在整个集群中更高效地分布式插入数据。
sh.shardCollection( "database.collection", { <field> : "hashed" } )
重要
一旦对某个集合进行分片后,片键的选择是不可变的。 也就是说,您不能再为该集合选择其他的片键。
如果您使用哈希片键对一个已经包含数据的集合进行分片操作:
- 在初始数据块创建之后,均衡器会在分片上适当地迁移这些初始数据块,并管理后续的数据块分配。
如果您使用哈希片键对一个空集合进行分片操作:
- 如果没有为空集合或不存在的集合指定区域和区域范围:
- 分片操作将创建空数据块,以覆盖片键值的整个范围,并执行初始数据块分配。默认情况下,该操作为每个分片创建2个数据块,并在整个集群中迁移。您可以使用
numInitialChunks
选项指定不同数量的初始块。数据块的这种初始创建和分配可以使分片设置更加快速。
- 初始分配之后,均衡器将管理后续的数据块分配。
- 如果已经为空集合或不存在的集合指定区域和区域范围(从MongoDB4.0.3版本起可用):
- 分片操作会为定义的区域范围以及所有其他分片创建空数据块,以覆盖片键值的整个范围,并根据区域范围执行初始数据块分配。数据块的这种初始创建和分配可以使分片设置更加快速。
- 初始分配之后,均衡器将管理后续的数据块分配。
另请参考:
译者:刘翔
校对:牟天垒