zookeeper leader选举机制

转载

最近看了下zookeeper的源码,先整理下leader选举机制


先看几个关键数据结构和函数

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

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

 

选票参数,还有Notification,参数也都差不多

 

复制代码
    static public class ToSend {
        long leader;                      //leader id
        long zxid;                         //选票的zxid
        long electionEpoch;                //投票轮数
        QuorumPeer.ServerState state;      //状态
        long sid;                           //投票人id
        long peerEpoch;                    //选票的epoch
    }
复制代码

 

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

    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. 发起投票:

  首先投票给自己,然后给所有Acceptor;

2. 等待ack

  先判断自身状态

    1)如果自身状态不是LOOKING:

      说明已经有多数派通过选举结果,直接将选举结果通知给来源方;

    2)如果自身状态是LOOKING:

      检查投票者状态:

        2.1)如果选票是LOOKING发起的,说明当前正在选举,需要收集选票,检查选举条件:

          首先检查选票轮数:
            如果小于自身投票的轮数,说明收到的选票过期,忽略;
            如果大于自身投票的轮数,说明自己已经out:
              清空选票箱,根据优先级更新自己的选票,然后notify;
            如果等于自身投票的轮数,投票有效:
              根据优先级更新自己的选票,然后notify;

          将选票投入选票箱;

          检查最新选票是否可以通过:

            不满足通过条件:
              继续等待新的选票:
            满足通过条件:
              接收新选票,看能否收到优先级更高的选票:
                如果有优先级高的选票,继续循环;
                否则投票结束,更新状态。
        2.2)如果选票是FOLLOWING、LEADING发起的,说明已有多数派通过选举,此时只需确认是否满足多数派:

          检查选票是否满足多数派:

            2.2.1)满足选票终结。
            2.2.2)继续循环等待


代码流程还算清晰,再来考虑下实际投票中可能情况,以上逻辑能否满足:

1. 一台宕机重启的机器加入已有环境

  此时肯定有一个多数派接收选票时进入状态1),这个多数派会将当前选举结果返回,这些选票的处理流程都会进入2.2,当所有选票收到时,2.2.1满足,选举结束

2. 一台机器加入正在投票中的环境

  如果当前机器的,如果所有server都会接受优先级最高的投票,投票会逐渐收敛,最高优先级最高的选票当选,选举结束;

3. 当集群中多数机器宕机重启

  存活的服务发现不满足多数派,改变状态为LOOKING,投票轮数+1, 然后重新开始投票,此时会进入上面情况2。

以上,只要有超过半数的机器存活,经过投票,收敛后,最终会完成投票。

你可能感兴趣的:(大数据-理论)