ZAB简介

Paxos

Paxos协议是由Leslie Lamport于1990年提出的一种基于消息传递的一致性算法,解决了分布式系统中如何就某个值达成一致的问题。Lamport在其论文中提出的算法也被称作basic paxos或classic paxos,在此算法基础上又衍生出了很多变种。由于网上已经有很多详细介绍paxos的资料,此处不再介绍。本文重点讲述paxos在工程上的一种实现形式。

需要解决的问题:

  1. paxos 存在活锁的可能,由于任何proposer都可以提出proposal,导致在phase1或者phase2都可能无法达到超过半数的acceptor响应,因此工程实践上必需对提出proposal做限制:要么由一个统一的角色来负责proposal的提出,要么限制每个proposer提出proposal的时间间隔
  2. 算法中acceptor,proposer,learner的身份在工程上如何表示
  3. 一台机器是否对应一种角色;如果由应用端担任一种角色(如客户端来参与决议过程),如何保证可靠性,可用性
  4. 这样一个解决一致性问题的装置到底能处理哪些经典的工程问题,需要提供什么样的API
  5. 是否能应用在大规模的集群上,性能和扩展性是否满足需求

相信每个人在学习paxos协议时都会产生这些问题:“如果让我来实现这个协议,应该是什么样子的?”

Chubby

Chubby是google发表的分布式锁服务,是理论与工程实践完美结合的产物。在我看来最大的贡献点是把一个复杂的协议完全形象化地应用在一个lock service或者naming service,并通过树形结构的数据库或者说一个轻量级的文件系统来实现。相对开发者来说,文件系统形态的API恐怕再熟悉不过了。而对于活锁问题,所有的proposal都由一个leader发出。对于扩展性和性能问题,google认为chubby是一个粗粒度的锁服务,明确说明“什么能做,什么不能做“(这个涉及到写敏感以及带宽的问题)。而对于读操作,通过proxy来解决了扩展问题。总之chubby把我们上面所提到的几个问题都很好地解决了。

Zookeeper

Zookeeper是参考了chubby的一种开源实现,整体设计分为leader,follower,observer(后两者统称为learner)

  • leader:将写请求广播给所有follower,一个系统只有一个leader,但leader可以由组成leader和follower的任何一台机器来担任,一旦选定leader,其余机器的角色为follower
  • follower:监听leader的proposal来完成事务;leader和follower都可以参与leader的选举
  • observer:作为proxy面向客户端,可以处理读请求,而写请求都转给leader处理,不参leader选举过程,同步所有数据更新

ZAB

ZooKeeper是一种primary-backup系统,其采用了ZAB(zookeeper atomic broadcast)协议来保证一致性。ZAB可以认为是paxos的一种变通,而在primay-backup数据更新时,表现形式非常像二阶提交(two phase commit)协议,但没有2pc的缺点:commit阶段,coordinator crash导致cohorts事务状态hang住,对于zookeeper来说会发起leader选举避免这一情况。ZAB协议包括了两部分:

  • 数据更新部分:如何保证primary-backup数据更新时的强一致性
  • leader选举部分:如何保证leader crash时,系统能选举出一个新的leader,同时又不影响数据一致性

ZAB与paxos不同之处在于他做了更多的限定:

PROPERTY

  1. 完整性(Integrity): 如果有一台机器接收到消息m,那么一定有某台机器广播了此消息m
  2. 全局有序(Total order): 如果一台机器先后接收到消息m1,m2,那么其他任何机器在收到消息m2时一定已收到m1

PROPERTY保证了ZAB满足PO因果序(PO causal order),这里所说的PO,可以理解为一种偏序关系(下面称PO关系)。为了理解什么是PO关系,先看几个定义:

DEFINITION 1

  1. 某台机器广播了消息,设值为v,序列号为z,则标记为abcast<v,z>事件
  2. 某台机器接收到消息,设值为v,序列号为z,则标记为abdeliver<v,z>事件
  3. epoch: ZAB协议在发生一次leader选举时会令epoch增加来表示leader发生变化。设当前序列号为z,则epoch标记为epoch(z)。此处z是64bit整型,高32bit代表epoch,低32bit代表当前序列号

接下来给出PO关系的定义:

DEFINITION 2

如果说事件e1和e2满足PO关系,标记为e1 < e2,那么当且仅当如下条件之一成立:

  1. e1,e2发生在同一台机器上,e1发生在e2之前,且至少成立其一:(1)e1不是abcast<v1,z1>,e2不是abdeliver<v2,z2>,或者(2)epoch(z1) = epoch(z2)。(z1 < z2)
  2. e1 = abcast<v1,z1>,e2 = abdeliver<v2,z2>
  3. 存在e3满足 e1 < e3且 e3 < e2

回过头来很容易看出满足上述PROPERTY的ZAB一定是PO因果序(PO causal order)。说了一大堆定义,绕来绕去,到底为了说明什么呢?我们知道一个事务的各个操作之间必须满足一定的顺序(如create节点一定要在update节点以及delete节点之前)。而在多副本构成的分布式数据库中,如果要保证事务的全局原子性与一致性,那么这种全局广播的因果序协议就成了关键所在。现在问题来了,如何保证PROPERTY成立呢?ZAB要求机器之间使用TCP通信,且同一时间只能有一条连接(除非连接断开,才会建立新的连接),此时很明显PROPERTY成立。至于Leader选举对PO因果序的影响,在ZAB的论文中已经给于证明:PROPERTY仍旧成立。

Leader选举

我们前面说过ZAB包含两部分,TCP通信只是保证ZAB协议数据更新部分满足PO因果序,leader选举部分对消息的顺序没有要求,这是因为leader选举用的是简化的paxos协议,因此TCP/UDP无所谓,事实上zookeeper两种协议都实现了。Leader选举部分的内容网上有很多资料,此处不打算细说,如果简单叙述就是:每次选举都是先广播自身投票,等待获取所有机器的投票信息,选择超过半数的投票value作为最终结果,否则选取当前最大序列号的proposal最为下次投票的value。Zookeeper代码实现中LeaderElection和FastLeaderElection的区别主要在于:前者需要收集全部投票结果后才做出结论,后者获取部分结果后,可以随时(1) 修改自身投票value后重新发出投票 (2) 直接终止选举获得最终结果。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值