chunk切分是根据分片策略进行实施的,分片策略的内容包括分片键和分片算法。
当前,MongoDB支持两种分片算法:
- 范围分片(range sharding)
假设集合根据x字段来分片,x的完整取值范围为[minKey, maxKey](x为整数,这里的minKey、maxKey为整型的最小值和最大值),其将整个取值范围划分为多个chunk。
如:
chunk1包含x的取值在[minKey,-75)的所有文档。
chunk2包含x取值在[-75,25)之间的所有文档,依此类推。
范围分片能很好地满足范围查询的需求,比如想查询x的值在[-30,10]之间的所有文档,这时mongos直接将请求定位到chunk2所在的分片服务器,就能查询出所有符合条件的文档。
范围分片的缺点在于,如果Shard Key有明显递增(或者递减)趋势,则新插入的文档会分布到同一个chunk,此时写压力会集中到一个节点,从而导致单点的性能瓶颈。
一些常见的导致递增的Key如下:
时间值。
ObjectId,自动生成的_id由时间、计数器组成
UUID,包含系统时间、时钟序列
自增整数序列
- 哈希分片(hash sharding)
哈希分片会先事先根据分片键计算出一个新的哈希值(64位整数),再根据哈希值按照范围分片的策略进行chunk的切分。
image.png哈希分片与范围分片是互补的,由于哈希算法保证了随机性,所以文档可以更加离散地分布到多个chunk上,这避免了集中写问题。然而,在执行一些范围查询时,哈希分片并不是高效的。因为所有的范围查询都必然导致对所有chunk进行检索,如果集群有10个分片,那么mongos将需要对10个分片分发查询请求。
哈希分片与范围分片的另一个区别是,哈希分片只能选择单个字段,而范围分片允许采用组合式的多字段作为分片键。
哈希分片仅支持单个字段的哈希分片:
{ x : "hashed" }
4.4 以后的版本,可以将单个字段的哈希分片和一个到多个的范围分片键字段来进行组合,比如指定 x:1,y 是哈希的方式:
{x : 1 , y : "hashed"}
分片键选择:
分片键的基数,取值基数越大越有利于扩展
分片键的取值分布应该尽可能均匀
业务读写模式,尽可能分散写压力,而读操作尽可能来自一个或少量的分片
分片键应该能适应大部分的业务操作
参考
全面剖析 MongoDB 高可用架构
https://mp.weixin.qq.com/s/jLsviuQ0wCcsmkskXSFdEQ
MongoDB分片(Sharding)技术
https://blog.csdn.net/weixin_52622200/article/details/121613135
mongoDB高可用部署架构——分片集群篇(Sharding)
https://developer.aliyun.com/article/879873
网友评论