1. ZooKeeper的协议

1.1 ZAB协议

要深入学习ZooKeeper前,胡广认为我们要先学习ZooKeeper的核心理念,所有的ZooKeeper行为都是围绕这个核心来进行的。说了那么多,它就是——ZAB协议。

ZAB协议英文全称叫ZooKeeper Atomic Broadcast,我们透过中文含义可以大概了解他做了什么事情:ZooKeeper原子消息广播协议。

来看看原子广播在维基百科的解释。

那ZooKeeper广播啥呢?我们知道ZooKeeper集群有Leader服务器、Follower服务器,这个Leader服务器接收了客户端所有的事务请求,事务请求可以是新增某一个ZNode节点,也可以是删除某一个ZNode节点。

这些事务请求的变更要不要提交、如何通知其他Follower服务器进行同步变更,这就是广播涉及的主要内容了。

ZAB协议主要包含了消息广播、崩溃模式,跟着胡广往下看看。

1.2 消息广播

ZAB协议的消息广播类似于二阶段提交过程。顾名思义事务最终的提交要分为两个阶段。

消息广播的流程如下:

(1)针对客户端的事务请求,Leader服务器会为其生成对应的事务Proposal,同时广播给集群中其余Followr机器。这个事务Proposal我们可以把他理解为事务提案。

(2)Follower服务器在接收到事务Proposal后会以事务日志形式写入到本地磁盘中,如果写入成功,则反馈一个Ack反馈给到Leader服务器。

(3)Leader服务器会收集其他Follower服务器的选票,只有半数的Follow服务器同意本次事务请求,那Leader服务器就会广播一个Commit消息,通知所有Follower服务器进行事务提交。

总结下来,也就是分为二个阶段,第一阶段是询问事务Proposal的写入尝试能否成功,第二阶段就是在Leader服务器、Follower服务器进行事务提交。

掌握ZooKeeper的二阶段提交及其优缺点-LMLPHP

1.3 消息广播的缺点

当然消息广播的二阶段提交有所缺点。

(1)在消息广播的第二阶段,如果有部分Follower服务器没有收到Leader服务器广播的事务提交消息,这就会出现数据不一致的情况了。

(2)单点问题。如果Leader服务器在第二阶段奔溃了,那其他Follower服务器仍然会处于锁定上一次事务资源的状态中。

(3)同步阻塞问题。参与一个客户端事务请求时,Leader、Follower服务器的其他逻辑都需要进行阻塞,直到等到上一个二阶段提交完成之后才会开始执行。

1.4. 崩溃模式

ZAB协议涉及Leader服务器、Follower服务器,Leader服务器充当了最重要的作用。如果Leader服务器崩溃了或者失去和Follwer服务器之间的联系,那上面胡广提到的二阶段提交各种问题很可能都会出现。

开头不是说ZAB协议包含了消息广播、崩溃模式?别慌,崩溃模式就是为此而生的。

崩溃模式总的来说就做了两个事情,我们记住这两点方便理解:一个是确保提交已经被Leader提交的事务Proposal,另一个是丢弃已经被跳过的事务Proposal。

(1)为了解决上文的第1点问题。Leader服务器会为每一个Follower服务器都准备一个Proposal消息队列,通过该队列发送那些没有被各Follower服务器同步的事务Proposal,同时在Proposal消息后面加上Commit消息让Follower服务器进行事务提交。这可以解决二阶段提交带来的数据不一致问题。

(2)为了解决上文的第2点问题。ZooKeeper设计了一个高32位的epoch,用来作为Leader服务器的标识;设计了一个低32位的事务偏移量ZXID,用来作为最新已提交事务的偏移量。

新的Leader服务器上线后,新的Leader服务器拥有集群里最大的事务偏移量,Leader服务器会和Follower服务器的ZXID进行比对,从而让Follower服务器回退被跳过的事务Proposal。

掌握ZooKeeper的二阶段提交及其优缺点-LMLPHP

结束: 

掌握ZooKeeper的二阶段提交及其优缺点-LMLPHP

09-12 17:22