在讲解Leader选举之前,我们先来了解一下Zookeeper节点的4种状态:
LOOKING:观望状态,开始进行 Leader 选举
LEADING:领导者状态,处于该状态的节点说明是角色已经是 Leader
FOLLOWING:跟随者状态,表示Leader已经选举出来,当前节点角色是 follower
OBSERVING:观察者状态,表明当前节点角色是 observer
ZooKeeper中,主要有Leader,Follower,Observer三个角色(三个角色的用法参考:ZooKeeper集群角色介绍),那么Leader角色又是怎么选举出来的呢?在Leader选举之前,我们应该了解一下什么时候开始leader选举工作:
Leader的选举分为如下两个过程:①集群启动的时候的Leader选举 ②Leader崩溃的时候的选举。接下来分别了解这两个过程中Leader的具体选举过程。
1.集群启动时的Leader选举
集群中每个节点启动的时候,状态都会是LOOKING,处于观望状态,接下来就开始进行选举主流程:
Leader的选举,至少需要两台机器(2n+1奇数台法则),我们选取三台机器组成的服务器集群为例。在集群的初始化阶段,当有一台服务器Server1启动时,它本身是无法进行和完成Leader选举的。当第二台服务器Server2启动时,这个时候两台机器可以相互通信,每台机器都试图找到Leader,于是进入Leader选举的过程。选举过程如下:
①每个Server发出一个投票。由于是初始情况,Server1和Server2都会将自己作为Leader服务器来进行投票,每次投票都会包含自己服务器的myid,zxid,epoch(本例默认都为0)信息,使用(myid,zxid,epoch)来标识。此时Server1的投票为(1,0,0),Server2的投票为(2,0,0),然后各自将这个投票信息发送给集群中的其他机器;
②接收到来自各个服务器的投票。集群中的每个服务器收到投票后,首先判断该投票的有效性,如检查时候是本轮投票(通过epoch来判断)、是否来自LOOKING状态的服务器。
③开始处理投票。针对每一个投票,服务器都需要将别人的投票邮箱和自己的投票进行PK,PK规则如下:
i.优先检查zxid。zxid比较大的服务器优先作为Leader(zxid大说明数据是最新的)
ii.如果zxid相同,那么就比较myid。myid较大的服务器作为Leader服务器(服务器id,在zoo.cfg中配置。myid越大,在leader选举机制中权重越大)
对于Server1而言,它的投票是(1,0,0),接收Server2的投票为(2,0,0)。首先会比较两者的zxid,均为0;再比较myid,此时Server2的myid最大,于是Server1会将自己的投票信息更新为(2,0,0),将自己的一票投递给Server2。在这种情况下再次重新投票,对于Server2而言,它不需要更新自己的投票,只是再次向集群中所有机器发出上一次投票信息即可。
④统计投票。每次投票后,服务器都会统计投票信息,判断是否已经有过半机器接收到相同的投票信息。对于Server1和Server2而言,都统计出集群中已经有两台机器接受了(2,0,0)的投票信息,过半机器同意(2>1.5),此时便认为已经选出了Leader节点。
⑤改变服务器的状态。一旦确定了Leader节点,其他的每个服务器就会去更新自己的状态,如果是Follower,那么就变更为FOLLOWING;如果是Leader,就变更为LEADING。
2.Leader崩溃时的选举
当集群中的leader服务器出现宕机或者(由于网络等原因)导致不可用状态时,那么整个集群将无法对外提供服务,而是进入到新一轮的Leader选举。服务器运行期间的Leader选举和启动时期的Leader选举基本过程是一致的。
①变更状态。Leader节点挂掉后,余下的除ObServer节点服务器外,都会将自己服务器的状态变更为LOOKING,然后开始进入Leader选举过程。
②每个Server会发出一个投票。在运行期间,每个服务器上的zxid可能不同,此时假定Server1的zxid为123,Server3的zxid为122(Server2节点挂掉了);在第一轮的投票中,Server1和Server3都会投自己,产生投票(1,123,0)和(3,122,0),然后各自将投票发送给集群中的所有机器。接受来自各个服务器的投票,与启动时过程相同。
③处理投票。与启动时过程相同,优先判断zxid,则此时,Server1将会成为Leader。
④统计投票。与启动时过程相同。
⑤改变服务器状态。与启动时过程相同。
博主写作不易,来个关注呗
求关注、求点赞,加个关注不迷路 ヾ(◍°∇°◍)ノ゙
博主不能保证写的所有知识点都正确,但是能保证纯手敲,错误也请指出,望轻喷 Thanks♪(・ω・)ノ