mongoDB的读书笔记(05)_【Sharding】(01)_分片的简介

来源:互联网 发布:ubuntu 关闭图形界面 编辑:程序博客网 时间:2024/05/16 23:33

本片文章大部分的语言来自于mongoDB的在线文档,所以只能算翻译啦,不算原创!(-。-;)

分片 Sharding

概念解说

说个题外话先,原来Shard和Sharding是两个词。。。
分片就是以复数台服务器来存储数据,来支持大数据量的存储以及高吞吐量的读写。

扩充模式

熟悉HDFS的人估计都对分片Sharding这个词不陌生,叫法可能各有差异,但是模式是一样的。当我们那个数据库系统大到我们的系统CPU以及硬盘以及内存支持不了的时候,我们的server就进入了服务的临界模式,到达这个状态的时候怎么办?一般是有两种方式

纵向扩充

这是最一般的方式,纵向扩充即我们的服务器进行自身的能力扩充,如CPU的增加,硬盘内存的增加。当然,这种模式会大规模的增加成本。比如,一般,云服务的提供商都会给定一个最大利用限度。

横向扩充

横向扩充是我们当下最最流行的方式,即集群模式的扩充。把大量的数据都分布到不同的机器上来横向减轻数据量的压力。如下图
这里写图片描述
通过横向的数据扩充可以把数据量分散到Shard集群中,提高数据的处理和吞吐量。当有1TB的数据的时候,我们可以像途中那样用四个节点进行横向分布扩展,每个节点假设平均分配256GB的的数据,当我们的总数居从1TB扩展到2TB的时候,我们每个节点的数据量也就是从256GB扩展到512GB,对于每个节点的数量也是一种减轻。当然,我们可以继续扩展Sharding的个数,来对数据进行更广的分配。

Sharding的概览

这里写图片描述

Shards

最底下的绿色区域。不用说,这个是Shard的持久层,数据的存储的地方。我们可能会有复数个Shard。这个图中标识的是Shard(replica set),啥意思?之前的文章中说过Replica set的概念,提供高可用性的集群。那么对于Shard来讲,每一个Shard可以扩充成一个Replica的副本集。那么Shards的个数可以看图,是2个以上。

Routers

和Shards一样,用复数,说明会有复数个。2个以上。
这个其实可以看成是mongos的实例集合,所有的App通过Routers来进行Shards的访问。为什么说是实例集合呢?因为这种Router可以有多个共通承担对Shards的访问,这种多Routers的模式其实也组成了一个Router的小集群,目的也是为了分散request的压力,类似我们经常见到的LB。

Config servers

首先,复数个,其次,要有三个哦,途中也确切标出了,3个必须,为啥3个的话后面还会说。这个Config的作用其实从名字也可以看出,是配置、映射的作用。HDFS中也有类似的namenode之类的概念。像springmvc2.5以前或者Struts1.x的配置文件一样,这个Config servers提供的的是一种映射,因为我们的数据在shards中被分片到了复数台机器上,那么过来一个命令或者处理,我们到底应该映射到哪一台机器上去做处理呢?这个就要借助Config servers来进行metadata的映射。

数据的划分

Sharding的目的是把数据分散到每一个节点上去,那么如何去把数据划分到各个节点,如何去识别他们呢?划分的话是通过Shard Key来进行的。

Shard Keys

Shard Key是document中的某一个或者复数个索引字段所形成。mongoDB把这些Shard Keys分割成大块的数据来进行分布(很类似HDFS哦)。分布的方式有两种,顺序分布和哈希分布。

顺序分布

这里写图片描述
顺序分布很好理解。我们的key可能是最小到最大的一个顺序分布,当我们去进行Sharding分区的时候,哦我们的这些数据按照图中来说被分成了4个大的数据块,买个数据块叫做一个Chunk。这些Chunks是互不重叠的。 如果是一个顺序分布的Sharding,紧挨着的Shard Keys所制定的数据很有可能在同一个Chunk中,而且也很有可能在同一个Shard中。
再说一句,Shard会有复数个,每个Shard中又会包含复数个Chunks。酱的关系。

哈希分布

这里写图片描述
意思很明确吧。根据hash算法来分配数据,而不是顺序分配。和顺序分布的一个相反的结果就是,连续紧挨着的数据可能不在同一个Chunk中。虽然官网没有进一步明确说,但我觉得不在同一个Shard的可能性也是很大的,因为下面还会说Shard的转移等等。

顺序分布与哈希分布的表现模式

从上面的定义其实可以看出,hash分布和顺序分布的侧重点是不同的。
顺序分布的方式可以很快的定义查找,我们需要的数据和内容很有可能是连续放置的,所以取得的时候也相对简单。但是,这种模式下,我们的数据分布却不会很平均,可能会出现极为不合理的分布形式,比如第一个Shard数据量很大,而其余的Shard几乎没有数据。导致我们的访问的时候也是会造成一个Shard的压力巨大,其他的Shard在空闲。
而哈希分布可以很好地解决这个问题,可以按照一定的算法使得数据的分布比较均匀达到”分配”这个目的。但是,当我们对一系列的数据进行请求或者查找的时候有可能会出现每个Shard都要进行查找请求的情况出现。

Tag aware Sharding

标记型分片模式。这算是一个人为参与的利用Tag来影响数据分配的方式,对于Shard Keys的范围进行Tag的定义,在进行Sharding分片的时候指定规则来影响Sharding的分片结果。

维持一个平衡的数据分布

切分数据

这里写图片描述
我们在RDB中其实有一个概念,那就是拆表,当我们的数据量很大的时候我们的访问已经无法得到有效支持的时候,最有效的手法就是拆表。所以,这里的切分数据和这个拆表的原理是一样的。我们可以指定一个Chunk的大小,当达到这个大小的时候便会出现途中的拆分。任何一个插入和修改都会触发切分数据的发生。

达到平衡

平衡这个处理算法可以是任何一个Router的实例来生成的一个后台的处理balancer,以此来进行数据Chunk的搬运。
举个例子来说,当一个Sharding环境中,Shard之间的数据量是不平衡的状况时,比如Shard1是100个Chunck,Shard2是1个Chunck,那么就会出现Shard1向Shard2的Chunks搬运,比如搬过去50个,达到两个Shard的平衡。
当搬运处理结束后,会直接通知到上文说到的Config Servers然后进行metadata的维护,告知Config我们的Chunk的分布,这样再有操作过来就可以准确地定位数据了。
当没有任何errors产生的时候,balancer不会删除Shard1的那搬过来的50个Chunks进而退出。最终,mongoDB会自动地删除这Shard1的50个Chunks。

对集群中进行增删Shards

增加Shard的话肯定会影响Shards的平衡,mongoDB会很快地对Shards们进行平均分配使得整体的集群达到一个平衡情况,反应是迅速的,但是达到平衡通常会经过一点时间。
而当我们删除一个Shard的时候,删除之前mongoDB会首先进行平衡,把需要删除的Shard的数据先平衡到其余的节点,当平衡完成后,metadata也被更新后,shard才会被安全地移除。

つづく・・・

0 0