一、概述

        ZAB全称Zookeeper Atomic Broadcast(Zookeeper原子消息广播协议),是Zookeeper数据一致性的核心算法。Zookeeper通过该协议实现了一种主备模式的系统架构来保持集群中各副本之间数据的一致性。

二、协议介绍

        ZAB协议的核心是定义了会改变Zookeeper服务器数据状态的事务请求的处理方式:
        所有事务请求必须由一个全局唯一的服务器来协调处理,这个服务器被称为Leader服务器,其余的服务器为Follower服务器。Leader服务器负责将客户端事务请求转换成事务提议,并将其发送给集群中所有的Follower服务器,然后等待所有Follower服务器的反馈,当超过一半的Follower服务器进行了正确的反馈,Leader服务器会再次向所有的Follower服务器分发commit消息,要求其将前一个提议进行提交。

        ZAB协议包含两种基本模式:崩溃恢复和消息广播。
        在整个服务框架启动的过程中,或者Leader服务器出现网络中断、崩溃退出或者重启等异常情况时,就会进入恢复模式,并选举产生新的Leader服务器。当选举产生了新的Leader服务器后,会与其他Follower服务器进行状态同步,当集群中有过半的Follower服务器与Leader服务器完成同步后,就会进入消息广播模式。
        当一台机器加入集群中时,如果已经存在一个Leader服务器,那么新加入的机器就会进入恢复模式,找到Leader服务器,与其进行数据同步,同步完成后进入消息广播模式。

        消息广播

        ZAB协议的广播过程使用的是原子广播协议,类似二阶段提交过程。针对客户端的事务请求,Leader服务器会为其生成对应的事务提议,并且在广播之前为这个事务分配一个全局单调递增的唯一ID,称为事务ID(ZXID)。由于ZAB协议要严格保证消息的因果关系,所以必须将每一个事务按照ZXID的先后顺序进行排序与处理。在广播过程中,Leader服务器会为每一个Follower服务器分配一个单独的队列,然后将需要广播的事务提议依次放入队列中,并根据FIFO策略进行发送。每一个Follower服务器接收到事务提议后,首先将其以事务日志的形式写到本地磁盘上,并在成功写入后反馈给Leader服务器一个Ack响应。当Leader服务器接收到超过半数的Ack响应后,就广播一个Commit消息给所有的Follower服务器通知其进行事务提交,同时Leader自身也会完成事务的提交。每一个Follower服务器在接收到Commit消息后,完成对事务的提交。

        崩溃恢复

        在消息广播的过程中,如果Leader服务器出现崩溃或者由于网络等原因导致Leader服务器与过半Follower服务器失去联系,就会进入崩溃恢复模式。在崩溃恢复的过程中,除了要快速选举出Leader外,还要保证选举后服务器数据的一致。因此需要确保已经在Leader服务器上提交的事务最终被所有服务器都提交,确保丢弃那些只在Leader服务器上出现的事务。对此,ZAB协议的选举算法通过保证选举出的Leader服务器拥有集群中所有机器最高编号(ZXID最大)的事务提议,来保证这个新选举出的Leader服务器一定具有已经提交的提议,同时可以省去Leader服务器检查提议的提交和丢弃这一工作。

        数据同步

        在Leader选举完成之后,正式工作之前,Leader服务器首先要确认事务日志中的所有提议是否已经被过半的服务器提交了。Leader服务器会将没有被各服务器同步的事务以提议消息的形式逐个发送给Follower服务器,并在提议消息后紧跟着发送一个Commit消息,表示该事务已被提交。当Follower服务器将所有其尚未同步的事务都从Leader上同步过来以后,Leader服务器会将该Follower服务器加入到真正可用的Follower服务器列表中。