vlambda博客
学习文章列表

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

ZAB(Zookeeper Atomic Broadcast)算法是Zookeeper为了实现分布式协调及数据一致性而设计的算法。相对于Raft算法,ZAB算法除了投票机制,还增加了节点ID和数据ID的比较来优先选主。


此系列文章先来分析ZAB Leader选举的原理及实现,在后续《分布式数据复制》的系列文章中,我们再回过头来实现ZAB算法的分布式数据复制功能。


Leader选举:

选举原则:在同一任职周期内,节点的数据ID越大,表示该节点的数据越新,数据ID最大的节点优先被投票。所有节点的数据ID都相同,则节点ID最大的节点优先被投票。当一个节点的得票数超过节点半数,则该节点成为主节点。


节点状态:

  • Looking,选举状态,集群中没有主节点,该节点进入投票阶段。

  • Leading,领导者状态,当前节点为主节点,向其他节点发送心跳消息。

  • Following,跟随者状态,集群中已经选出主节点,则该节点转换成跟随者状态,接收主节点发送的心跳消息。

  • Observing,观察者状态,没有投票权和选举权,接收主节点发送的数据同步消息。


消息类型:

  • Vote,投票消息,包含节点数据ID(zxID),节点ID(serverID),选举周期(epoch),被选举节点ID(voteID)。

  • Heartbeat,心跳消息,Follower接收Leader的心跳消息,重置选举计时器。


选举过程:

  1. 节点刚启动时,默认为Following状态。

  2. 节点启动后,状态切换为Looking状态,先投票给自己,然后将投票消息发送给其他节点。投票消息:Vote(epoch, zxID, serverID)。

  3. 节点收到其他节点的投票消息后,比较zxID和serverID选出主节点,将选出主节点的投票消息广播给其他节点。

  4. 选出的主节点计算得票数,如果超过集群中节点半数,则切换为Leading状态,并向其他节点发送心跳消息。

  5. 其他节点切换为Following状态。


假设有3个节点,选举过程如下图:


  1. 初始3个节点都是Following状态,数据ID都为0。

  2. 各节点epoch加1,切换为Looking状态,然后投票给自己,再把投票消息广播出去,voteID是自身节点ID。

  3. 节点收到投票消息后,由于epoch和数据ID都一致,所以将自己的票都投给节点ID最大的节点3,voteID修改为3,再次将投票消息广播出去。

  4. 节点3计算得票数,如果大于节点半数,则切换为Leading状态,成为主节点。向其他节点发送心跳消息,其他节点切换为Following状态。


网络分区:

网络分区恢复后的处理机制与Raft相似,可以参考Raft算法系列文章来了解。


总结:

ZAB选举算法,节点有Following、Looking、Leading和Observing 4种状态;节点数据ID和节点ID最大,且得票数过半才能成为主节点。因此算法时间相对较长,但是稳定性在三种选主算法中最好。节点故障恢复或者网络分区恢复后,会触发选主,但是不一定真正切主,只有符合选主原则的节点才能成为主节点。


ZAB算法的Leader选举原理讲解完了,下一篇文章《分布式选举-ZAB算法-2 Leader选举 代码实现》我们来具体看看如何用代码实现分布式环境下的ZAB Leader选举。






鼓励一下,点个“在看”