暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

MongoDB | 分片式集群架构

架构之旅 2017-04-24
582

1. MongoDB Sharded Cluster

使用场景

MongoDB目前有3大核心优势:灵活性 + 高可用性 + 可扩展性。


灵活性是通过json文档来实现,而高可用性则是通过复制集来保证,分片集群模式则保证了可扩展性。


当MongoDB复制集遇到下面的业务场景时,你就需要考虑使用分片集群(Sharded cluster ):


1) 存储容量需求超出单机磁盘容量,无法通过 垂直扩展来满足应用的需求;


2)活跃的数据集超出单机内存容量,导致很多请求都要从磁盘读取数据,影响性能;


3)写IOPS超出单个MongoDB节点的写服务能力;


4)垂直扩展的成本大于水平扩展时;


如下图所示,Sharded cluster 模式使得集合的数据可以分散到多个Shard(复制集或者单个Mongod节点)存储,使得MongoDB具备了横向扩展(Scale out)的能力,丰富了MongoDB的应用场景。



2. MongoDB Sharded cluster 架构

MongoDB通过配置 集群 支持分片,如下图所示,由Shard、Mongos和Config server 3个组件构成。



 1 

Mongos

Mongos是Sharded cluster的访问入口 , 也就是请求路由,它与应用接口,转发应用的请求到某个Shard。一个集群可以包含多个mongs来分发请求,为了保持系统的高可用性,通常会有多个mongos实例来组成路由。


 2 

Config Server

Mongos本身并不持久化数据,Sharded cluster所有的元数据都会存储到Config Server,而用户的数据则会分散存储到各个shard。Mongos启动后,会从config server加载元数据,开始提供服务,将用户的请求正确路由到对应的Shard。


 3 

Shards

Shards是用来存储数据和,每一个Shard都是由独来的mongod实例或者是Replica Set构成, 为了系统的高可用性和数据的一致性,在产品集群环境通常采用Replica Set来搭建Shard. 关于Relplia Set的搭建稍后我会专门来介绍。


3. 数据分片策略

Sharded cluster支持将单个集合的数据分散存储在多个shard上,用户可以指定根据集合内文档的某个字段即shard key来分布数据,目前主要支持2种数据分布的策略,范围分片(Range based sharding)或hash分片(Hash based sharding)。


Shard Keys决定了集群中一个集合的 documents 在不同 shards 中的分布.片键字段必须被索引,且在集合中的每条记录都不能为空,可以是单个字段或复合字段. Shard Key的选择必须慎重,一旦选好后就不可以更改。而且Shard Key的选择也将会影响集群的性能,效率和扩展,即使拥有了最好性能的硬件和基础设施的集群Shard Key也有可能成为它的瓶颈。


 1 

范围分片

采用区间分区时shard key必须是数字类型,整个区间的上下边界分别为“正无穷大”、“负无穷大”,每个数据块覆盖一段子区间,即整体而言,任何shard key均会被某个特定的数据块所覆盖。区间都是左闭右开,区间之间不会有重叠覆盖,且互相临近。当然数据块并不是预先创建的,而是随着数据块数据的增大而不断分割。

范围分片能很好的满足『范围查询』的需求,比如想查询x的值在[-75, 25]之间的所有文档,这时mongos直接能将请求路由到Chunk2,就能查询出所有符合条件的文档。


范围分片的缺点在于,如果shardkey有明显递增(或者递减)趋势,则新插入的文档多会分布到同一个chunk,无法扩展写的能力,比如使用_id作为shard key,而MongoDB自动生成的id高位是时间戳,是持续递增的。当shard key是单调递增时,范围分片会导致数据分布不均,因为在一定时间内,所有write请求(读取最新数据的read请求)将会映射到一个shard上,即少数shards在某段时间内承载了系统的大部分请求。


2

Hash分片

Hash分片是根据用户的shard key计算hash值(64bit整型),根据hash值按照『范围分片』的策略将文档分布到不同的chunk。Hash值具有很强的散列能力,通常不同的shard key具有不同的hash值(冲突是有限的),这种分区方式可以将document更加随机的分散在不同的chunks上。


Hash分区正好相反,即使是单调递增的shard key,它们的Hash值也有较大不同,因此这些数据将会比较随机的分散在多个数据块上,但是这引入了range查询的问题,临近的shard key可能分布在不同的chunks上甚至是shards上,这意味着range查询需要访问所有的shards,特别是在有sort、limit等操作时。


4. Mongos


Mongos作为Sharded cluster的访问入口,所有的请求都由mongos来路由、分发、合并,这些动作对客户端driver透明,用户连接mongos就像连接mongod一样使用。

Mongos会根据请求类型及shard key将请求路由到对应的Shard


1

查询请求

查询请求不包含shard key,则必须将查询分发到所有的shard,然后合并查询结果返回给客户端

查询请求包含shard key,则直接根据shard key计算出需要查询的chunk,向对应的shard发送查询请求

2

写请求

写操作必须包含shard key,mongos根据shard key算出文档应该存储到哪个chunk,然后将写请求发送到chunk所在的shard。

3

更新/删除请求

更新、删除请求的查询条件必须包含shard key或者_id,如果是包含shard key,则直接路由到指定的chunk,如果只包含_id,则需将请求发送至所有的shard。

 4 

其他命令请求

除增删改查外的其他命令请求处理方式都不尽相同,有各自的处理逻辑,比如listDatabases命令,会向每个Shard及Config Server转发listDatabases请求,然后将结果进行合并。


5.Config Server

1

config database

Config server存储Sharded cluster的所有元数据,所有的元数据都存储在config数据库,3.2版本后,Config Server可部署为一个独立的复制集,极大的方便了Sharded cluster的运维管理。

2

config.shards

config.shards集合存储各个Shard的信息,可通过addShard、removeShard命令来动态的从Sharded cluster里增加或移除shard。如下所示,cluster目前拥有2个shard,均为复制集。

3

config.databases

config.databases集合存储所有数据库的信息,包括DB是否开启分片, primary shard信息,对于数据库内没有开启分片的集合,所有的数据都会存储在数据库的primary shard上。

 4 

config.colletions

数据分片是针对集合维度的,某个数据库开启分片功能后,如果需要让其中的集合分片存储,则需调用shardCollection命令来针对集合开启分片。

 5 

config.chunks

集合分片开启后,默认会创建一个新的chunk,shard key取值[minKey, maxKey]内的文档(即所有的文档)都会存储到这个chunk。当使用Hash分片策略时,也可以预先创建多个chunk,以减少chunk的迁移。

当chunk里写入的数据量增加到一定阈值时,会触发chunk分裂,将一个chunk的范围分裂为多个chunk,当各个shard上chunk数量不均衡时,会触发chunk在shard间的迁移。

6

config.settings

config.settings集合里主要存储sharded cluster的配置信息,比如chunk size,是否开启balancer等

7

config.locks

config.locks存储锁相关的信息,对某个集合进行操作时,比如moveChunk,需要先获取锁,避免多个mongos同时迁移同一个集合的chunk。




“呐,做人呢,最重要的就是开心啦”

梦想重要,开心也重要

有时呢,我们真的需要一点无厘头的小幽默

祝每一位热爱技术的小伙伴们都开开心心


欢迎关注架构之旅

敏捷团队管理 | 热点技术  




文章转载自架构之旅,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论