1. ZAB 协议

在 ZAB ( ZooKeeper Atomic Broadcast , ZooKeeper 原子消息广播协议) 协议的事务编号 Zxid设计中,Zxid 是一个 64 位的数字,其中低 32 位是一个简单的单调递增的计数器,
针对客户端每一个事务请求,计数器加 1;而高 32 位则代表 Leader 周期 epoch 的编号,每个当选产生一个新的 Leader 服务器,就会从这个 Leader 服务器上取出其本地日志中最大事务的 ZXID,
并从中读取epoch 值,然后加 1,以此作为新的 epoch,并将低 32 位从 0 开始计数。

事务编号 Zxid(事务请求 epoch + 计数器),Zxid(Transaction id)类似于 RDBMS 中的事务 ID,用于标识一次更新操作的 Proposal(提议)
ID。为了保证顺序性,该 zkid 必须单调递增。

1.2 epoch

epoch:可以理解为当前集群所处的年代或者周期,每个 leader 就像皇帝,都有自己的年号,所
以每次改朝换代,leader 变更之后,都会在前一个年代的基础上加 1。这样就算旧的 leader 崩溃
恢复之后,也没有人听他的了,因为 follower 只听从当前年代的 leader 的命令。

2. ZAB协议的两种模式

  • 恢复模式(选主)
  • 广播模式(同步 )

Zab 协议有两种模式,它们分别是恢复模式(选主)和广播模式(同步)。当服务启动或者在领导
者崩溃后,Zab 就进入了恢复模式,当领导者被选举出来,且大多数 Server 完成了和 leader 的状
态同步以后,恢复模式就结束了。状态同步保证了 leader 和 Server 具有相同的系统状态。

3. ZAB协议的4阶段

3.1 选举阶段

Leader election, 选出准Leader

节点在一开始都处于选举阶段,只要有一个节点得到超半数
节点的票数,它就可以当选准 leader。只有到达 广播阶段(broadcast) 准 leader 才会成
为真正的 leader。这一阶段的目的是就是为了选出一个准 leader,然后进入下一个阶段。

3.2 发现阶段

Discovery, 接受提议、生成epoch、接受epoch

在这个阶段,followers 跟准 leader 进行通信,同步 followers
最近接收的事务提议。这个一阶段的主要目的是发现当前大多数节点接收的最新提议,并且
准 leader 生成新的 epoch,让 followers 接受,更新它们的 accepted Epoch

一个 follower 只会连接一个 leader,如果有一个节点 f 认为另一个 follower p 是 leader,f
在尝试连接 p 时会被拒绝,f 被拒绝之后,就会进入重新选举阶段。

3.3 同步阶段

Synchronization, 同步follower 副本

同步阶段主要是利用 leader 前一阶段获得的最新提议历史,
同步集群中所有的副本。只有当 大多数节点都同步完成,准 leader 才会成为真正的 leader。
follower 只会接收 zxid 比自己的 lastZxid 大的提议。

3.4 广播阶段

leader 消息广播

到了这个阶段,Zookeeper 集群才能正式对外提供事务服务,并且 leader 可以进行消息广播。同时如果有新的节点加入,还需要对新节点进行同步。

ZAB 提交事务并不像 2PC 一样需要全部 follower 都 ACK,只需要得到超过半数的节点的 ACK 就可以了。