发布于 

ZAB 协议详解

  1. ZAB 的分类角色:
  • Leader
  • Follower
  • Observer

读取时:客户端连接 zk 的任一节点,节点直接拿出自己对应的数据返回,这时该节点扮演 Observer 角色;
写入时:客户端的任一提交都会由 Leader 去广播给所有的节点,有半数以上的节点写入成功即视为写入成功;

ZAB 的所有动作都是节点们通过协议同步的

ZAB 节点的 struct:

  • history:当前节点接收到事务提议的 log
  • epoch: 年代
  • currentEpoch: 当前年代
  • acceptedEpoch: Follower 已经接收 LEADER 发起的 NEWEPOCH 提议
  • lastZxid: history 中接收到的最近的提议的 zxid(最大值)

ZAB 中节点的三种状态:

  • election/looking
  • following
  • leading

提议的 struct:

  • epoch: 当前的年代
  • zxid: 当前年代的事务 id
  • serverid: 配置 zoo.cfg 中的 myid,用于标识在集群中的 num
    当节点收到每个提议时会比较 提议的 epoch 和 zxid,如果提议的 epoch 大于等于自己当前的 epoch,则判断 zxid 是否大于 lastZxid;提议的 zxid>lastZxid 则考虑接受,否则丢弃

ZAB 的三个阶段:

  1. Fast Leader Election(快速选举阶段)
  2. Recovery Phase(恢复阶段)
    1. Discovery(发现阶段)
    2. Synchronization(同步阶段)
  3. Broadcast Phase(广播阶段)
  • Fast Leader Election
    这个阶段,生成准 leader,每个节点都会投票给自己,所有节点的状态处于election/looking。

    1. 选举开始,每个节点为自己生成一个投给自己的投票,并把投票分发给所有的节点,然后节点启动一个接收线程接收其他节点投来的选票,并对选票进行处理,最终选出 leader。
    2. 当接收到其他节点的选票时,会和自己的投票进行比较,如果比自己的投票好(首先判断 epoch 是否比自己的大,如果相等,继续判断 zxid 是否比自己的大,如果还是相等,则看下 serverid 是否比自己的大,取最大的为最终的选票),则更新自己的选票,更新选举轮数(logicalclock),并把接收来的选票记录到选票表(记录投给谁以及票数)中,如果自己的投票好,也记录到选票表中,再次把最好的选票分发给所有节点
    3. 接下来节点统计选票表中的选票结果,当一个节点的选票超过半数,则把该节点当做 Leader,如果该节点就是自己,则置自己的状态为 Leading,否则为 Following
    4. 图片展示:
      名词解释:
      • electionEpoch: 当节点把自己的选票投给别的节点时,struct 里的当前选举轮数(可以理解为当前节点的 logicClock)
      • logicClock: 表示选举轮数,当节点启动时,初始值为0。如图,在选举的时候会+1,当其他节点的 electionEpoch>logicClock 时,也会被赋值为 electionEpoch
  • Recovery Phase

    • Discovery
      这个阶段是followers 发起的,followers 和准 leader 进行通信,同步 followers 最近接收的事务提议。该阶段的主要目的是发现当前大多数节点接收的最新提议,并且让准 leader 生成新的 epoch,让 followers 接收,并更新 followers 的 acceptEpoch。一个 follower 只会连接一个 leader,如果有一个节点 f 认为另一个 follower p 是 leader,则 f 会去和 p 进行通信,f 在连接 p 的时候会被拒绝,然后 f 进入选举阶段
    • Synchronization
      同步阶段主要是 leader 将 Discovery 阶段获得的最新提议历史,同步集群中所有的副本。只有当集群中大多数节点都同步完成,准 leader 才会成为真正的 leader。follower只会接收 zxid 比自己的 lastZxid 大的提议
      quorum: 是指半数以上的节点
  • Broadcast Phase
    原子广播阶段,到了这个阶段,zk 集群才能正式对外提供事务服务,leader 可以进行消息广播。同时如果有新的节点加入,还需要对新的节点进行同步

崩溃恢复保证数据一致性
主从架构下,leader 崩溃,为了保证数据一致性,会在选出新leader后进入恢复阶段,新 leader 具有所有已经提交的提议,因此它会保证让 followers 同步已经提交的提议,丢弃未提交的提议(以 leader 的记录为准)
history.lastCommittedZxid:最近被提交的提议的 zxid
history:oldThreshold:被认为已经太旧的已提交提议的 zxid

参考文章:
http://blog.xiaohansong.com/2016/08/25/zab/
https://yq.aliyun.com/articles/46994