我们继续互联网技术架构-分布式存储。 总目录:
分布式存储作为互联网之核心基石,没有分布式海量存储就好比无源之水。分布式系统不是什么新鲜事物,教科书里已经研究了好多年,但是不温不火,直到近年互联网大数据应用的兴起才使得它大规模的应用到工程实践中,其主要特点概括为:规模大+成本低。现在的大型互联网公司少则几百几千个PC服务器,多的达到数百万级别低成本PC服务器集群; 总体来说,分布式存储需要具备以下一些要素:
分布式存储的挑战来源自于其设计的两个技术领域:分布式 + 存储:
分布式存储数据分类: 按照其所处理的数据类型来分的话,大体分为
分布式存储系统分类: 有了数据,我们看一下容器如何划分:
分布式存储包括了数据的分布,复制,一致性,容错等。
一致性:分布式存储系统会将数据冗余备份,称之为replication/copy. 副本是目前分布式存储系统容错的唯一方法。如有3个客户端A,B,C
数据分布:分布式存储当然会设计数据如何分布了,同时要考虑自动负载均衡 哈希分布:无需多说,类似HashMap的index了,基本思路都是选取某业务相关主键key,然后 hash(key) % N(服务器数量), 当然如果这里hash函数的散列性比较好的话,数据可以比较均匀的分布到集群。 上面可以么?如果仔细看过HashMap的极客们应该知道,当HashMap的数量超过一定负载后,需要resize, rehash。这有什么问题么?内存处理当然没什么大问题,这可是分布式存储啊,你这么一resize,rehash可不得了,涉及很多数据的迁移,耗时耗力。况且,分布式会动态增加,卸载节点,都不用超过一定数量限制。如何解决? 一致性哈希(Distributed Hash Table, DHT):算法如下,给系统每个节点分配一个随机token,使得这些token构成一个哈希环,存放时,根据hash(key)的值,存放到顺时针第一个大于/等于该值的token所在节点。这样,每次节点的变更只会影响哈希环中相邻的节点,对其他没有影响。
如上图所示,假设哈希空间为0-2^32-1大小:
2>采用同样算法计算待存储对象的key的hash值,将其分配到这个圆环 通过上图可以看出对象与机器处于同一哈希空间中,在这样的部署环境中, hash环是不会变更的,因此,通过算出对象的hash值就能快速的定位到对应的机器中,这样就能找到对象真正的存储位置了。 上文提到,普通hash求余最大问题就是当count也就是机器的数量变化,如添加,删除后,需要rehash,并进行位置调整。我们来看一下一致性哈希如何处理:
如图,灰色的node2被删除,则只需按照瞬时针迁移,object3则会被迁移到 node3中,所以仅仅会影响object3位置,其他对象无需改动。 2. 节点添加 如果我们要在集群中添加一个新的节点node4,通过哈希算法得到key4,并映射到环中。
按照顺时针迁移规则,我们把object2迁移到node4中,其他object保持原位。 另外,稍微提及一下,当一致性哈希算法在服务节点太少时,容易因为节点分部不均匀而造成数据倾斜问题。为了解决这种数据倾斜问题,一致性哈希算法引入了虚拟节点机制,即对每一个服务节点计算多个哈希,每个计算结果位置都放置一个此服务节点,称为虚拟节点。
顺序分布:通常做法是将一个大表顺序划分成连续范围,即子表。如经常用来举例的用户表,按照主键分为1-10000,10001-20000,... 80000-90000等。再添加类似B+树索引。其中叶子相当于子表。 分布式复制:replication,常见做法类似数据库同步操作日志(commit log) 容错:容错是分布式存储系统设计的重要目标,当然是自动容错。
重要的分布式协议:Paxos选举协议与两阶段提交协议。其中Paxos协议在我们介绍ZK的时候,就有小伙伴提出详细介绍。 两阶段提交协议:Two-phase Commit, 2PC. 主要用来确保多个节点或者分布式操作的原子性。如果有使用过JTA或者做过大型银行转账系统的应该使用过。 如跨数据库操作:
恰如其名,2PC通常分为两个阶段: 阶段1: 请求阶段Prepare Phase, 协调者通知参与者准备提交或者取消事务; 阶段2: 提交阶段Commit Phase, 协调者将阶段1的结果进行投票表决,当且仅当所有参与者同意提交事务时,协调者才通知所有参与者提交,否则通知所有参与者取消。 如下图所示:
两阶段提交协议是阻塞协议,执行过程中需要加锁,且无法容错,所以... 大多数分布式存储系统都避而远之。同理可证,JTA。 Paxos协议:主要用于解决多个节点之间一致性问题。如主节点出现故障时,其它节点如何协调选主。同时,当做到了多个节点之间的操作日志一致性,就能够在这些节点上来构建高可用服务包括分布式锁,分布式命名,配置服务等。 多数情况下,系统只有一个备点提议者Proposer, 所以它的提议总是会很快被大多数节点接受。 执行步骤:
如果系统有多个proposer,则各自分别发起提议,如修改操作或者提议自己选主,如果proposer第一次发起的accept请求没有被acceptor中多数派批准,则需要进行一轮完整的Paxos协议,如下:
1. 准备prepare: Proposer首先选择一个提议序号n给其它acceptor节点发送 prepare消息,Acceptor收到消息后,如果提议序号已经大于它已经回复的所有prepare消息,则acceptor将自己上次接受的提议回复给proposer,并承诺不再回复小于n的提议。 2. 批准accept:Proposer收到了acceptor中多数派队prepare的回复后,就进入批准阶段。如果在之前的prepare阶段acceptor回复了上次接受的提议,则提议值发给acceptor批准。Acceptor在不违背它之前在prepare阶段的承诺前提下接受这个请求。如果超过一半的acceptor接受,提议值生效,Proposer发送acknowledge消息通知所有acceptor。 稍微有点绕,Paxos需要确保2点,正确性,即只有一个提议值会生效;可终止性,即最终会有一个提议值生效。数学语言,有且只有一个。 受限与篇幅以及时间,我们会分2篇来介绍分布式存储系统。下一篇将提及著名Google分布式数据库 “The largest single database on earth”。 公众号:技术极客TechBooster
|
|