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的心跳消息,重置选举计时器。
选举过程:
-
节点刚启动时,默认为Following状态。
-
节点启动后,状态切换为Looking状态,先投票给自己,然后将投票消息发送给其他节点。投票消息:Vote(epoch, zxID, serverID)。
-
节点收到其他节点的投票消息后,比较zxID和serverID选出主节点,将选出主节点的投票消息广播给其他节点。
-
选出的主节点计算得票数,如果超过集群中节点半数,则切换为Leading状态,并向其他节点发送心跳消息。
-
其他节点切换为Following状态。
假设有3个节点,选举过程如下图:
-
初始3个节点都是Following状态,数据ID都为0。
-
各节点epoch加1,切换为Looking状态,然后投票给自己,再把投票消息广播出去,voteID是自身节点ID。
-
节点收到投票消息后,由于epoch和数据ID都一致,所以将自己的票都投给节点ID最大的节点3,voteID修改为3,再次将投票消息广播出去。
-
节点3计算得票数,如果大于节点半数,则切换为Leading状态,成为主节点。向其他节点发送心跳消息,其他节点切换为Following状态。
网络分区:
网络分区恢复后的处理机制与Raft相似,可以参考Raft算法系列文章来了解。
总结:
ZAB选举算法,节点有Following、Looking、Leading和Observing 4种状态;节点数据ID和节点ID最大,且得票数过半才能成为主节点。因此算法时间相对较长,但是稳定性在三种选主算法中最好。节点故障恢复或者网络分区恢复后,会触发选主,但是不一定真正切主,只有符合选主原则的节点才能成为主节点。
ZAB算法的Leader选举原理讲解完了,下一篇文章《分布式选举-ZAB算法-2 Leader选举 代码实现》我们来具体看看如何用代码实现分布式环境下的ZAB Leader选举。
相关代码地址:https://github.com/Justin02180218?tab=repositories
更多【分布式专辑】系列文章,请关注公众号