zookeeper leader选举机制源码
发布日期:2021-06-28 21:03:25 浏览次数:2 分类:技术文章

本文共 2129 字,大约阅读时间需要 7 分钟。

zk节点状态:

服务可能处于的状态,从名字应该很好理解:

public enum ServerState {
  LOOKING, FOLLOWING, LEADING, OBSERVING;}

开始这个选举算法前,每个节点都会在zoo.cfg上指定的监听端口启动监听(server.1=127.0.0.1:20881:20882),这里的20882就是这里用于选举的端口。

每个集群中的节点都有一个状态 LOOKING, FOLLOWING, LEADING, OBSERVING。都属于这4种,每个节点启动的时候都是LOOKING状态,如果这个节点参与选举但最后不是leader,则状态是FOLLOWING,如果不参与选举则是OBSERVING,leader的状态是LEADING。

选票的比较逻辑

选票的比较逻辑也很简单,依次比较几个关键字段

protected boolean totalOrderPredicate(long newId, long newZxid, long newEpoch, long curId, long curZxid, long curEpoch) {
... return ((newEpoch > curEpoch) || ((newEpoch == curEpoch) && ((newZxid > curZxid) || ((newZxid == curZxid) && (newId > curId))))); }
  1. 判断消息里的epoch是不是比当前的大,如果大则消息里id对应的server我就承认它是leader

  2. 如果epoch相等则判断zxid,如果消息里的zxid比我的大我就承认它是leader

  3. 如果前面两个都相等那就比较一下server id吧,如果比我的大我就承认它是leader。

关于前面两个东西暂时我们不去关心它,对于新启动的集群这两者都是相等的。

那这样看来server id的大小也是leader选举的一环啊(有的人生下来注定就不平凡,这都是命啊)。

最后我们来看看,很多文章所介绍的,如果超过一半的人说它是leader,那它就是leader的逻辑吧

private boolean termPredicate(            HashMap
votes, Vote vote) {
HashSet
set = new HashSet
(); //遍历已经收到的投票集合,将等于当前投票的集合取出放到set中 for (Map.Entry
entry : votes.entrySet()) {
if (self.getQuorumVerifier().getVotingMembers().containsKey(entry.getKey()) && vote.equals(entry.getValue())){
set.add(entry.getKey()); } } //统计set,也就是投某个id的票数是否超过一半 return self.getQuorumVerifier().containsQuorum(set); } public boolean containsQuorum(Set
ackSet) {
return (ackSet.size() > half); }

最后一关:如果选的是自己,则将自己的状态更新为LEADING,否则根据type,要么是FOLLOWING,要么是OBSERVING。

到这里选举就结束了。

第一次启动选举:

第一次启动epoch和zxid这两个参数都是相等即为0,
这里介绍的是一个新集群启动时候的选举过程,启动的时候就是根据zoo.cfg里的配置,向各个节点广播投票,一般都是选投自己。然后收到投票后就会进行进行判断。如果某个节点收到的投票数超过一半,那么它就是leader了。

一半以上follower挂掉:

一个集群有3台机器,挂了一台后的影响是什么?挂了两台呢?

挂了一台:挂了一台后就是收不到其中一台的投票,但是有两台可以参与投票,按照上面的逻辑,它们开始都投给自己,后来按照选举的原则,两个人都投票给其中一个,那么就有一个节点获得的票等于2,2 > (3/2)=1 的,超过了半数,这个时候是能选出leader的。

挂了两台: 挂了两台后,怎么弄也只能获得一张票, 1 不大于 (3/2)=1的,这样就无法选出一个leader了。

转载地址:https://blog.csdn.net/yangshengwei230612/article/details/117512963 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:spark和flink的区别
下一篇:Spark sql常用方法

发表评论

最新留言

做的很好,不错不错
[***.243.131.199]2024年04月01日 16时56分18秒