ZAB
ZooKeeper没有完全采用Paxos算法,而是使用了一种ZooKeeper Atomic Broadcast原子消息广播协议作为一致性算法。
它是能维持顺序的一致性算法。
Zookeeper如何使用ZAB
ZAB是一种支持崩溃恢复的原子广播协议,Zookeeper通过它实现了一种主备模式的系统架构来保持集群中各副本之间的数据一致性。
具体来说:
- 所有事务请求必须由一个全局唯一服务器协调处理,Leader,而其余为Follower
- Leader负责将客户端的请求转换为Proposal提议,分发给Follower
- 超半Follower反馈正确,再次Leader发送Commit消息。
协议介绍
ZAB包含两种基础模式,崩溃恢复和消息广播。
当网络中断,重启,崩溃时,使用崩溃恢复,其余消息广播模式。
消息广播
类似二阶段提交过程,但是不要求所有Follower都返回Ack,只需要半数通过提议就可以commit了。
另外,消息广播协议是使用具有FIFO特性的TCP协议来进行通信的,所以很容易地保证消息广播过程中消息接收和发送的顺序性。
Leader为每个事务请求生成一个全局的递增的事务ID(ZXID),用对应的Proposal来进行广播。
同时,Leader为每一个Follwer都维持一个FIFO队列,然后按序发送。
崩溃恢复
当Leader服务器发生崩溃,或者由于网络原因导致Leader和半数以上Follower失联,那么就会进入崩溃恢复状态。
崩溃恢复最重要的就是实现一个高效的选举Leader,同时让所有Follower感知到被选举出的Leader。
基本特征:
- ZAB协议需要确保那些在Leader上提交过的Proposal被所有Follower提交。(当Leader刚刚Commit了一个Proposal它就崩溃了)
- 需要丢弃那些只在Leader服务器上被提出的事务。(Leader刚提出Proposal就崩溃了)
总的来说,Leader崩溃前提交了的Proposal需要所有Follower都提交,Leader崩溃前提出但没提交的Proposal需要丢弃。
基于基本特征实现的Leader选举
基于此:只需要选举的Leader是拥有最大ZXID(事务最大编号)即可保证,Leader拥有所有已提交的Proposal。
ZAB的事务编号ZXID
ZXID是一个64位的数字,其中低32位是一个递增的计数器,而高32位代表了Leader周期的epoch编号,每当选举产生Leader时,epoch就会加1.
数据同步
完成Leader选举后,会进行数据同步。
就是Leader将每个Follower没有的数据,通过各自Follower的队列提议然后提交。
深入理解ZAB的特性和实现细节
系统模型要为业务服务,zookeeper需要保证高吞吐和低延迟的特性,高并发下的实现数据一致性,并且能优雅地处理故障。
zookeeper的配置文件
zookeeper的进程都有相同(或者相似)的配置文件,其中包括的各个节点的id,ip,端口,选举端口等。
主进程周期
当Leader选举出来,消息同步后,各个进程才会向上层接口告知可以进行事务提交。
事务
每一个事务标识<e,c>,前者时主进程周期epoch,后者是epoch内的事务计数count。
主进程每次对事务函数调用都包含了,事务内容和事务标识。
算法描述
阶段一:发现
就是Leader选举,用于在多个分布式进程中选举出一个主进程。
先比ZXID,如果ZXID相同,则比较节点id;
新节点加入集群不会立刻导致重新选举,而是成为Follower进行同步,从而保证这个过程的平稳。
以3个进程为例:
1号进程启动,自己投自己一票,成为leader。
2号启动,加入集群,成为Follower,和1号进程进行数据同步。
3号启动,加入集群,成为Follower,和1号进程进行数据同步。
阶段二:同步
Follower学习Leader。
阶段三:广播