上一篇介绍了 mongo 的三种部署方式,「单点、主从、副本集」三种部署方式,今天就跟大家聊聊最后一种「分片集群」的方式,分片集群也是 mongo 能够作为万亿级别数据库的核心魅力所在,也有一句话说到:
「连分片集群都不知道,你还好意思说自己用过 mongo ?」
其他的不多说,我们先甩一张分片集群的架构图
在分片集群当中,一共有以下三种角色
一个集群包含了多个分片组成,而一个分片又存储了多个块(每个块包含一定范围片键的数据,互不相交且并集为全部数据),一个块当中包含了多个文档。
那么问题来了-
mongo 提供了「三种方式来做数据分片」
这是很多技术最常用的一种方式,就是将数据通过 hash 散列化,打在不同的机器上,实现「均匀分布」,但是它很大的问题就是「数据不连续」,比如业务需要查询工资在 10000~20000 之间的人员,你可能就需要遍历每一个分片了
这种策略直接根据片键的范围确定分片。
比如现在我们将数据在逻辑上分为四个块。
在数据上数据 工资 0~5000一个块,5000~10000 一个块,10000~15000 一个块,15000~20000 一个块,20000~25000 一个块,25000 以上一个块,由于公司人员薪资分布大概率都在 5000~15000,这个区域内,就会造成数据过分集中在 5000~10000 、10000~15000 这两个块儿中,造成「数据分布不均匀」,但是再做「范围查询的时候效率就会很高」
简单来说 Zone 实际上像是范围分片的另一个版本,你为一定范围内的片键制定一个 Zone,然后再将一些分片加入到这个Zone中,于是这一范围内的数据最终就将存储在这个 Zone 中的分片上。
随着数据慢慢的写入,数据量越来越大,当 Chunk 增长到指定大小(默认为 64MB)时,MongoDB 会 对 Chunk 进行分裂。
Chunk 分裂的⽅式
JumboChunk 是一个最小的 Chunk 可以「只包含一个唯一的 ShardKey」,这样的 Chunk 不可以再进行分裂。
这个时候就要说到我们的 「balancer(平衡器)」 了,用来「保证集合的 Chunk 在各个 Shard 上是均衡的」。
当某些分片数据不均匀的情况下,balancer 会发出一个命令让切割器去需要移动的分片上去做数据切割,再把数据移动到数据少的分片上。具体的步骤如下:
迁移过程对于应用是透明的,但由于「迁移过程会占用相应节点的 CPU 和带宽资源」,因此对分片集有一定程度的性能影响,并且对运维操作存在一些限制。
「不可以」
MongoDB 中没有对集合分片后更改片键的自动支持。如果在集合分片后必须更改片键,可以按如下方式操作:
每个 mongos 实例都「维护一个与分片集群成员的连接池」。客户端「一次请求就会占用一个连接」,客户端请求完成后,连接释放。但是客户端数量减少时,这些池不会收缩。这可能导致未使用的mongos占用大量打开的连接。如果 mongos 不再使用,则可以安全地重新启动进程以关闭现有连接。
今天的内容只讲了分片集群相关的,当你看完了以上内容时,再来看看以下几个问题,「mongoDB 分片集群架构是怎么样的?有哪三种分片方式?块分裂是什么?为什么会有块分裂?分片之间的负载均衡是怎么做的?如何修改分片键?mongos 如何管理与分片之间的连接?」
你都会了吗?