Ch02-Zookeeper 之 ZAB 协议

Ch02-Zookeeper 之 ZAB 协议

April 3, 2018
Apache Zookeeper
zookeeper

Zab 协议的全称是 Zookeeper Atomic Broadcast(Zookeeper 原子广播),Zab 是特别为 Zookeeper 设计的支持崩溃恢的原子广播协议,在 Zookeeper 中主要依赖 Zab 协议实现数据一致性,基于该协议,Zookeeper 实现了主备模型(Leader 与 Follower)的系统架构保证集群中各个副本之间的数据一致性。

1. 工作原理 #

在 Zookeeper 中只有一个 Leader,并且只有 Leader 可以处理外部客户端的事务请求,并将其转换成一个事务 Proposal,然后 Leader 服务器再将事务 Proposal 操作的数据同步到所有 Follower(数据广播/数据复制)。ZAB 协议规定,只要超过半数 Follower 节点反馈 OK,Leader 节点就会向所有的 Follower 服务器发送 Commit 消息。即将 Leader 节点上的数据同步到 Follower 节点之上。

2. 工作模式 #

Zookeeper 正常情况下,会工作在消息广播模式,但是如果 Leader 宕机或者过半数 Follower 失联,那么会工作在崩溃恢复模式。

2.1 消息广播模式 #

  1. Leader 服务器将客户端的 request 请求转化为事务 Proposal 提案,同时为每个 Proposal 分配一个全局唯一的 ID,即 ZXID;
  2. Leader 服务器与每个 Follower 之间都有一个队列,Leader 将消息发送到该队列;
  3. Follower 机器从队列中取出消息处理 (写入本地事务日志中) 完成后,向 Leader 服务器发送 ACK 确认;
  4. Leader 服务器收到半数以上的 Follower 的 ACK 后,即认为可以发送 commit;
  5. Leader 向所有的 Follower 服务器发送 commit 消息。

2.2 崩溃恢模式 #

2.2.1 需要遵循的原则 #

该模式做数据恢的时候主要遵循两个原则,已经处理过的消息不能丢被丢弃的消息不能再现

  • 对于第一个原则,Leader 收到超过半数 Follower 的 ACKs 后就向各个 Follower 广播 Commit 消息,如果在此期间 Leader 宕机了,那么后续新选举出来的 Leader 在数据恢复完成后要保证所有的 Server 都成功执行前面部分 Follower 完成的事务。
  • 对于第二个原则,Leader 已经生成 Proposal 提案但是还没有发给 Follower 的时候,Leader 宕机了。新的 Leader 选取成功,旧的 Leader 注册称为 Follower 之后必须放弃先前的 Proposal 提案。

2.2.2 执行过程 #

崩溃恢复模式一般会经过两个执行过程,Leader 选举和初始化同步

Leader 选举

  1. 节点刚启动时,默认为 Following 状态。
  2. 节点启动后,状态切换为 Looking 状态,先投票给自己,然后将投票消息发送给其他节点。投票消息内容为 Vote(Epoch, ZXID, ServerID)。
  3. 节点收到其他节点的投票消息后,比较 ZXID 和 ServerID 选出主节点,将选出主节点的投票消息广播给其他节点。
  4. 选出的主节点计算得票数,如果超过集群中节点半数,则切换为 Leading 状态,并向其他节点发送心跳消息。
  5. 其他节点切换为 Following 状态

对于节点已经启动后,Leader 宕机后的 Leader 选举过程跟上述过程类似,唯一不同的是第 1 步中所有的节点不是 Following 状态,会先将自己的状态改为 Looking。剩余过程依旧一致。

初始化同步

当完成 Leader 选举后,此时的 Leader 还是一个准 Leader,其要经过初始化同步后才能变为真正的 Leader。

  1. 为了保证 Leader 向 Learner 发送提案的有序,Leader 会为每一个 Learner 服务器准备一 个队列;
  2. Leader 将那些没有被各个 Learner 同步的事务封装为 Proposal;
  3. Leader 将这些 Proposal 逐条发给各个 Learner,并在每一个 Proposal 后都紧跟一个 COMMIT 消息,表示该事务已经被提交,Learner 可以直接接收并执行
  4. Learner 接收来自于 Leader 的 Proposal,并将其更新到本地;
  5. 当 Learner 更新成功后,会向准 Leader 发送 ACK 信息;
  6. Leader 服务器在收到来自 Learner 的 ACK 后就会将该 Learner 加入到真正可用的 Follower 列表或 Observer 列表。没有反馈 ACK,或反馈了但 Leader 没有收到的 Learner,Leader 不会将其加入到相应列表。

3. 参考文献 #

分布式选举-ZAB 算法 -1 Leader 选举 原理


4. 其他问题 #

0x01 ZAB 协议与 2PC 有何不同?

ZAB 协议简化了 2PC 事务提交:

  • 去除中断逻辑移除,Follower 要么 Ack,要么抛弃 Leader;
  • Leader 不需要所有的 Follower 都响应成功,只要一个多数派 ACK 即可。

0x02 ZXID 长什么样?

ZAB 中每个事务对应一个 ZXID,它由两部分组成:<e, c>,e 即 Leader 选举时生成的 epoch,c 表示当次 epoch 内事务的编号、依次递增。 假设有两个事务的 ZXID 分别是 z、z’,当满足 z.e < z’.e 或者 z.e = z’.e && z.c < z’.c 时,定义 z 先于 z’发生 (z < z’)。

0x03 Learner 是什么?

Learner 跟 Leader 和 Follower 不同,它并不是 ZooKeeper 的一种实际角色,属于一种逻辑概念,一般指 Follower 和 Obverser。