分⽚(sharding)是MongoDB⽤来将⼤型集合⽔平分割到不同服务器(或者复制集)上所采⽤的⽅法。不需要功能强⼤的⼤型计算机就可以存储更多的数据,处理更⼤的负载——其采用的扩展方式两种:1)垂直扩展:增加更多的CPU和存储资源来扩展容量;2)⽔平扩展:将数据集分布在多个服务器上。⽔平扩展即分⽚。 

  对于分片,MongoDB官网给出了分配集群内部互相工作的结构图:

    

datagrip mongodb集群 mongodb集群原理_服务器

分⽚集群由以下3个服务组成:

每个shard由⼀个或多个mongod进程组成,⽤于存储数据。

数据库集群的请求⼊⼝,所有请求都通过Router(mongos)进⾏协调,不需要在应⽤程序添加⼀个路由选择器, Router(mongos)就是⼀个请求分发中⼼它负责把应⽤程序的请求转发到对应的Shard服务器上。

    3)Config Server: 配置服务器。存储所有数据库元信息(路由、分⽚)的配置。

  Shards和Config Server均是复制集。

  Config Servers和Shard均是复制集。具体分片应用流程可总结为如下图:

      

datagrip mongodb集群 mongodb集群原理_datagrip mongodb集群_02

为了在数据集合中分配⽂档, MongoDB使⽤分⽚主键分割集合;同时提供了两种分片策略:1)范围分⽚(Range based sharding);2)hash分⽚(Hash based sharding)

      

datagrip mongodb集群 mongodb集群原理_datagrip mongodb集群_03

  范围分片:

在⼀个shard server内部, MongoDB还是会把数据分为chunks,每个chunk代表这个shard server内部⼀部分数据。chunk是在一个特别shard中连续的片键值,MongoDB分割分⽚数据到区块,每⼀个区块包含基于分⽚主键的左闭右开的区间范围。

      

datagrip mongodb集群 mongodb集群原理_服务器_04

范围分⽚是基于分⽚主键的值切分数据,每⼀个区块将会分配到⼀个范围。范围分⽚适合满⾜在⼀定范围内的查找,例如查找X的值在[20,30)之间的数据, mongo 路由根据Configserver中存储的元数据,可以直接定位到指定的shard的Chunk中。

    缺点: 如果shard key有明显递增(或者递减)趋势,则新插⼊的⽂档多会分布到同⼀个chunk,⽆法扩展写的能⼒。

  hash分⽚(Hash based sharding):

    Hash分⽚是计算⼀个分⽚主键的hash值,每⼀个区块将分配⼀个范围的hash值。

        

datagrip mongodb集群 mongodb集群原理_服务器_05

分⽚与范围分⽚互补,能将⽂档随机的分散到各个chunk,充分的扩展写能⼒,弥补了范围分⽚的不⾜,缺点是不能⾼效的服务范围查询,所有的范围查询要分发到后端所有的Shard才能找出满⾜条件的⽂档。