加入收藏 | 设为首页 | 会员中心 | 我要投稿 核心网 (https://www.hxwgxz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 教程 > 正文

带着问题学习分布式系统之数据分片

发布时间:2018-09-03 02:53:45 所属栏目:教程 来源:xybaby
导读:正文 在前文中,提出了分布式系统(尤其是分布式存储系统)需要解决的两个最主要的问题,即数据分片和数据冗余,下面这个图片(来源)形象生动的解释了其概念和区别: 其中数据即A、B属于数据分片,原始数据被拆分成两个正交子集分布在两个节点上。而数据集C属

前面也提到,如果使用非sharding key去访问数据,那么元数据服务器(或者元数据缓存服务器,后面会讲解这一部分)是没法知道对应的数据在哪一个shard上,那么该访问就得发送到所有的shard,得到所有shard的结果之后再做聚合,在mongoDB中,由mongos(缓存有元数据信息)做数据聚合。对于数据读取(R: read or retrieve),通过同一个字段获取到多个数据,是没有问题的,只是效率比较低而已。对于数据更新,如果只能更新一个数据,那么在哪一个shard上更新呢,似乎都不对,这个时候,MongoDB是拒绝的。对应到MongoDB(MongoDD3.0)的命令包括但不限于:

findandmodify:这个命令只能更新一个document,因此查询部分必须包含sharding key

  • When using findAndModify in a sharded environment, the query must contain the shard key for all operations against the shard cluster for the sharded collections.

update:这个命令有一个参数multi,默认是false,即只能更新一个document,此时查询部分必须包含sharding key

  • All update() operations for a sharded collection that specify the multi: false option must include theshard key or the _id field in the query specification.

remove:有一个参数JustOne,如果为True,只能删除一个document,也必须使用sharidng key

另外,熟悉sql的同学都知道,在数据中索引中有unique index(唯一索引),即保证这个字段的值在table中是唯一的。mongoDB中,也可以建立unique index,但是在sharded cluster环境下,只能对sharding key创建unique index,道理也很简单,如果unique index不是sharidng key,那么插入的时候就得去所有shard上查看,而且还得加锁。

接下来,讨论分片到shard上的数据不均的问题,如果一段时间内shardkey过于集中(比如按时间增长),那么数据只往一个shard写入,导致无法平衡集群压力。

MongoDB中提供了"range partition"和"hash partition",这个跟上面提到的分片方式 hash方式, ranged based不是一回事儿,而是指对sharding key处理。MongoDB一定是ranged base分片方式,docuemnt中如是说:

  • MongoDB partitions data in the collection using ranges of shard key values. Each range defines a non-overlapping range of shard key values and is associated with a chunk.

那么什么是"range partition"和"hash partition",官网的一张图很好说明了二者的区别:

带着问题学习分布式系统之数据分片
带着问题学习分布式系统之数据分片

上图左是range partition,右是hash partition。range partition就是使用字段本身作为分片的边界,比如上图的x;而hash partition会将字段重新hash到一个更大、更离散的值域区间。

hash partition的最大好处在于保证数据在各个节点上均匀分布(这里的均匀指的是在写入的时候就均匀,而不是通过MongoDB的balancing功能)。比如MongoDB中默认的_id是objectid,objectid是一个12个字节的BSON类型,前4个字节是机器的时间戳,那么如果在同一时间大量创建以ObjectId为_id的数据 会分配到同一个shard上,此时若将_id设置为hash index 和 hash sharding key,就不会有这个问题。

当然,hash partition相比range partition也有一个很大的缺点,就是范围查询的时候效率低!因此到底选用hash partition还是range partition还得根据应用场景来具体讨论。

最后得知道,sharding key一但选定,就无法修改(Immutable)。如果应用必须要修改sharidng key,那么只能将数据导出,新建数据库并创建新的sharding key,最后导入数据。

元数据服务器

在上面讨论的三种数据分片分式中,或多或少都会记录一些元数据:数据与节点的映射关系、节点状态等等。我们称记录元数据的服务器为元数据服务器(metaserver),不同的系统叫法不一样,比如master、configserver、namenode等。

元数据服务器就像人类的大脑,一只手不能用了还没忍受,大脑不工作整个人就瘫痪了。因此,元数据服务器的高性能、高可用,要达到这两个目标,元数据服务器就得高可扩展 -- 以此应对元数据的增长。

元数据的高可用要求元数据服务器不能成为故障单点(single point of failure),因此需要元数据服务器有多个备份,并且能够在故障的时候迅速切换。

有多个备份,那么问题就来了,怎么保证多个备份的数据一致性?

多个副本的一致性、可用性是CAP理论讨论的范畴,这里简单介绍两种方案。第一种是主从同步,首先选出主服务器,只有主服务器提供对外服务,主服务器将元数据的变革信息以日志的方式持久化到共享存储(例如nfs),然后从服务器从共享存储读取日志并应用,达到与主服务器一致的状态,如果主服务器被检测到故障(比如通过心跳),那么会重新选出新的主服务器。第二种方式,通过分布式一致性协议来达到多个副本件的一致,比如大名鼎鼎的Paxos协议,以及工程中使用较多的Paxos的特化版本 -- Raft协议,协议可以实现所有备份均可以提供对外服务,并且保证强一致性。

HDFS元数据

HDFS中,元数据服务器被称之为namenode,在hdfs1.0之前,namenode还是单点,一旦namenode挂掉,整个系统就无法工作。在hdfs2.0,解决了namenode的单点问题。

带着问题学习分布式系统之数据分片

(编辑:核心网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读