哈希分片使用跨共享集群分区数据。 哈希索引计算单个字段的哈希值作为索引值;此值用作切片键。
哈希分片在分片集群中提供了更均匀的数据分布,这是以减少为代价的。 Post-hash后,具有相近切片键值的文档不太可能位于相同的块或切片上 -- 更可能执行来满足给定的范围查询。可以将相等匹配的查询定向到单个片片。
Tip: MongoDB在使用哈希索引解析查询时会自动计算哈希。 应用程序不需要计算哈希。
警告:MongoDB哈希索引在计算哈希前会将浮点数截断为64位整数。 例如,哈希索引将为值分别为2.3、2.2和2.9的字段存储相同的值。 为了防止冲突,对于不能可靠地转换为64位整数的浮点数,不要使用哈希索引。 MongoDB哈希索引不支持大于 2^53 的浮点值。要查看键的哈希值是什么,请参见 .
从4.0版本开始,shell提供了 方法。 此方法使用与哈希索引相同的哈希函数,并可用于查看键的哈希值。
Hashed Sharding Shard Key
选择作为哈希切片键的字段应该具有良好的基数,或者具有大量不同的值。 哈希键非常适合具有像值或时间戳之类变化字段的切片键。 一个很好的例子是默认 _id
字段,假设它只包含 值。
要使用哈希切片键对集合进行切片处理,请参见 。
哈希和范围切片
给定一个集合,使用单调递增的值x作为切片键,使用范围切片会导致传入的 inserts 的分布类似于以下内容:
由于X的值总是在增加,所以以为上界的块接收大多数传入的写操作。 这将插入操作限制在包含此块的单个切片中,从而减少或消除了切片集群中分布式写的优势。
通过对X使用哈希索引,inserts的分布如下所示:
如图所示,由于数据现在分布得更加均匀, inserts 在整个集群中得到了有效的分布。
分片集合
使用 方法,指定集合的完整命名空间和要用作的目标。
sh.shardCollection( "database.collection", {: "hashed" } )
分割一个已填充的集合
如果使用哈希切片键对已填充的集合进行切分:
- 分片操作创建初始块,以覆盖分片键值的整个范围。 创建的块的数量取决于 配置。
- 在初始块创建之后,平衡器将这些初始块适当地迁移到切片中,并继续管理块分布。
切分一个空集合
如果使用哈希切片键对空集合进行切分 :
- 没有为空集合或不存在的集合指定时:
- 切片操作创建空块,以覆盖切片键值的整个范围,并执行初始块分布。 默认情况下,操作会为每个切片创建2个块,并在集群中迁移。 可以使用
numInitialChunks
选项来设置初始块的数量。 这种初始化创建和块的分布允许更快地切片建立。 - 在初始分布之后,均衡器将会继续管理块的分布。
- 切片操作创建空块,以覆盖切片键值的整个范围,并执行初始块分布。 默认情况下,操作会为每个切片创建2个块,并在集群中迁移。 可以使用
- 为空集合或不存在的集合指定(从MongoDB 4.0.3开始可用) 时:
- 分片操作为已定义的区域范围以及任何其他块创建空块,以覆盖切分键值的整个范围,并根据区域范围执行初始块分布。 这种块的初始化创建和分发允许更快地建立分区切片。
- 在初始分布之后,均衡器将会继续管理块的分布。