前言
在zookeeper的上一篇文章中对zookeeper做了初步的了解,知道了他的基本命令,节点特性,以及集群的搭建。但是zookeeper是如何做到保证分布式一致性的呢?——ZAB协议。
ZAB协议
ZAB协议(Zookeeper Atomic Broadcast Zookeeper原子广播协议),它是一种支持
崩溃恢复
和原子广播
的协议,其核心是:所有的事物请求必须由一个全局唯一的服务器(Leader)来协调,Leader服务器负者将一个事物请求转换成一个事物Proposal,并将该Proposal分发给Follower,然后Leader服务等待所有Follower服务器的反馈,一旦超过半数以上的Follower服务器同意,则Leader会再次向所有Follower服务器分发Commit消息,将该Proposal进行提交.
下面我们分别讲解原子广播和崩溃恢复过程
原子广播
Leader服务器针对事物请求生成Proposal,分配一个全局单调递增的唯一的事物id(zxid),并将其发送给集群中其余的Follower,当有过半的Follower反馈Ask之后就开始提交该Proposal而不需要等到所有的Follower节点返回,假如上述中的一个Follower挂掉了,整个ZK集群是不会中断服务的,因为Leader依然能获得过半服务器(包括Leader自己)的支持.但是如果Leader服务器出现崩溃或者由于网络原因导致Leader服务器与过半Follower服务器失去联系,那么就会进入崩溃恢复模式.
崩溃恢复
ZAB协议为了保证一个事物在一台机器上处理成功,那么就应该在所有的机器上处理成功,哪怕机器处于故障崩溃.为了保证这一特性在崩溃恢复阶段需要确保:1、已经被Leader提交的Proposal也能被所有的Follower提交((当Leader向Follower发出commit消息后挂了);2、丢弃那些只在Leader服务器上被提出的事物(当Leader提出事物Propsal后来立即就挂了).崩溃恢复包括两个阶段:1、Leader选举 2、数据同步
Leader选举
Leader选举包括两类
- 1、 服务器启动时期的Leader选举
初始阶段,服务器都会将自己作为Leader进行投票,每次投票需要包括:myid 和ZXID,由于是初始阶段ZXID都为0,则会选取myid最大的服务器作为Leader服务器
- 2、服务器运行期间的Leader选举(崩溃阶段的)
优先比较ZXID,ZXID大的服务器优先作为Leader
如果ZXID相同则比较myid,myid较大的服务器作为Leader
数据同步
当Leader服务器被重新选举后,会将那些没有同步到各个Follower的事物以Proposal消息的形式逐个发送给Follower服务器,并在每个Proposal消息后面紧接着发一个commit消息,以确保已经被Leader提交的Proposal也能被所有的Follower提交.
同时由于ZXID是一个64位的数字,其低32位可以看做是一个单调递增的计数器,每一次Leader选举成功后会将低32位从0开始重新生成,高32位是当前Leader周期epoch编号,该epoch编号随着每一次的Leader选举递增,有点类似于朝代的概念。基于这样的策略,当上一个包含未被提交的事物的服务器重启时,由于当前集群中一定包含了更高epoch的事物id,因此该未被提交的事物机会被丢弃,这就确保了丢弃那些只在Leader服务器上被提出的事物。
当同步完成后,该集群又将进入消息广播阶段。