MongoDB有三大核心优势:【灵活模式】+【高可用性】+【可扩展性】,通过JSON文档来实现灵活模式,通过复制集(replica set)保证高可用,通过sharded cluster来保证可扩展性。下面我们就来详细说一下mongodb sharded cluster。
-
为什么需要shard cluster?
当MondoDB复制集遇到下面的业务场景时,就需要考虑使用sharded Cluster:- 存储容量需求超过单机的磁盘容量
- 读写能力受单机限制(读能力也可以在复制集里加 secondary 节点来扩展),可能是 CPU、内存或者网卡等资源遭遇瓶颈,导致读写能力无法扩展。
sharded Cluster使得集合的数据分散到多个shard(复制集或者单个mongodb节点)存储,使得mongodb具备了横向扩展的能力。如下图:
Shard
-
具体的mongodb sharded cluster的架构如下图:
mongodb sharded cluster.png- [shard] : 每个shard是已经分片的数据的子集。从3.6版本开始,每个shard必须部署成复制集(replica set,不能是单个mongodb节点)。
- [mongos-router] : mongos是一个查询路由器的角色, 提供了mongo client访问sharded cluster的接口,为了支持高可用性,可以部署多个mongos,常见的是一台应用服务器上部署一个mongos,这样可以减少client到router之间的网络延时。
- [config servers] : config server存储了cluster的元数据以及配置数据,从3.4版本开始config server也必须部署为复制集(replica set)。
-
数据分布策略
Sharded cluster支持将单个集合的数据分散存储在多个shard上,用户可以指定根据集合内文档的某个字段即shard key来分布数据,目前主要支持2种数据分布的策略,范围分片(Range based sharding)或hash分片(Hash based sharding)。-
范围分片:能够很好的支持基于shard key的范围查询。
范围分片
如上图所示使用x字段进行范围分片,将整个取值范围划分为多个chunk,每个chunk(通常配置为64M,一个chunk只会存在于一个shard上,每个chunk的配置信息保存在config server中,当查询或者保存的时候,mongos会根据shard key的计算出应该到那个shard上查询或者保存数据。)包含一小段数据。
-
hash分片:通常能够将写入均衡的分布到各个shard。
hash分片是根据shard key计算hash 值(64bit整型),根据hash值按照【范围分片】的策略将文档分布到不同的chunk。
hash分片
Hash分片与范围分片互补,能将文档随机的分散到各个chunk,充分的扩展写能力,弥补了范围分片的不足,但不能高效的服务范围查询,所有的范围查询要分发到后端所有的Shard才能找出满足条件的文档。
-
-
选择shard key时要注意下面几个问题:
- shard key取值范围太小,比较GPS位置的表中车牌号作为shard key会导致分片的效果不佳,因为车牌号范围太小,不够分散。
- shard key 某个值的文档特别多,这样导致单个 chunk 特别大(即jumbo chunk),会影响chunk 迁移及负载均衡。就如第一个问题中所说的使用车票号作为shard key进行范围分片,就会导致单个chunk特别大,同一个 车牌号对应的数据无法进一步细分,只能分散到同一个 chunk,会造成 jumbo chunk
- 根据非 shard key 进行查询、更新操作都会变成 scatter-gather 查询,影响效率。因此要使用业务中常用的查询field作为shard key。
网友评论