ZAB选主机制

what

  ZAB是zookeeper中支持崩溃恢复的一致性协议。基于该协议,zookeeper构建主从模式的架构,从而支持集群中各副本的数据一致性。

  工作方式:所有更新操作,都会发往主结点(Leader),然后主结点(Leader)将日志写入本地日志,再将日志复制到从结点(follower)。如果Leader故障,就会从follower群里再选一个主。(和raft类似)

 

  election epoch:分布式系统中,无法使用精准的时钟来维护事件的先后。Lampert提出的Logical Clock就成为了界定事件顺序的最主要方式。分布式系统中以消息标记事件,每个消息都会加上一个逻辑的时间戳(即Logical Clock)。在ZAB协议中,该Logical Clock就是zxid(全局唯一)。zxid是64位的数值,由Leader来生成,其高32位即为epoch,低32位是该epoch中的自增id;新选Leader的epoch会比老的大(一版是加1)。类比历史朝代,epoch就是朝代,自增id就是该朝代的记事了。

 

  结点的三状态:LOOKING/FOLLOWING/LEADING

    LOOKING: 节点正处于选主状态,对外提供服务,直至选主结束;

    FOLLOWING:作为系统的从节点,接受Leader主节点的更新并写入本地日志;

    LEADING:为系统主节点,接受client客户端更新,写入本地日志并复制到从节点;

  

 

when(选主时机)

  结点启动

    每个结点启动时都是LOOKING状态,处于观望态,然后进行选主;

  Leader结点异常

    Leader结点会定期的向followers发送心跳信息(即ping),如果一个follower未收到心跳,那么该follower的状态就会由FOLLOWING变为LOOKING,然后进入选主阶段;

  多数Follower结点异常

   Leader结点也会检查Followers结点的状态,如果多数Follower结点不再响应Leader结点(可能Leader和Follower结点之间的网络发生了分区)。此时,该Leader将不再是合法的Leader了,需要重新选主;

 

how(如何选主):

  选主参与者:

    发起选主者; 集群其他参与者(为发起者投票);

 

  选主依据:

    election epoch(A) > election epoch (B);

    zxid(A) > zxid(B);

    sid(A) > sid(B);

 

  选主流程:

    1、发起者A初始化自身的zxid和epoch:updateProposal();

    2、向其他所有节点发送选主通知:sendNotifications();

    3、A等待其他节点的回复:recvqueue.poll();

    4、如果B节点(参与者)的回复不为空,且B是一个有效节点,判断B此时的运行状态是LOOKING(也在发起选主)还是LEADING/FOLLOWING(正常请求处理过程);

 

  B结点LOOKING状态:

    1、A发起一次选主请求,并将请求广播至B、C节点,而此时B、C也恰好处于LOOKING状态:

    

 

    2、B、C节点处理A的选主消息,其中,B接受A的提议,C拒绝A的提:

        伴随着A的选主消息,B和C此时都获得了A节点选主的结果(A投票给自己,记录为<A, A>),并记录该信息,作为后续判断大家是否达成一致的标准。

  

 

     3、B将处理结果通知A、C:

        a、B更新了自己的投票,从投票给自己变成投票给A,因此根据协议的定义,需要将该消息散出去。而C由于拒绝了A的提议,因此,无需扩散消息;

        b、B将消息扩散给A和C的同时,A和C也就了解了B的投票信息,可以更新本地的投票信息表;      

 

     4、C同时也发起选主:

  

 

 

     5、A、B分别处理C的选主请求:

        A和B判断得出C是最合适的Leader,因此A和B都更新自己的候选Leader为C;同时由于C的消息,A和B都更新自身维护的投票信息,增加C的投票信息。

 

    6、A、B将更新后的信息扩散到其他节点:

  

 

     7、选主结束:所有的节点都已经达成了一致:每个节点都同意节点C作为新的Leader。

 

  B结点是FOLLOWING/LEADING状态:

    可能情况:

      1、结点A(Follower,发起选主者)与Leader出现网络问题而触发一次选主,但是其他Follower与Leader正常;

      2、结点A加入集群;

 

    方案1:Logical Clock相同,如果Sender(发起者)宣称自己是Leader,那么判断是不是半数以上的服务器都选举它,如果是设置角色并退出选举。

    方案1具体情况:A、B同时发起选主,此时他们的election epoch可能相同。如果B率先完成了选主过程(B可能变成了Leader,也有可能B选择了其他节点为Leader),但是A还在选主过程中。那么B就将自己的选主结果和自己的状态(LEADING/FOLLOWING)连同自己的election epoch回复给A。此时,A就是出现了1的情况,如下图:10表示选主的Logical Clock。

 

 

    方案2:LogicalClock不同时,说明在另一个选举过程中已经有了选举结果。

     方案2具体情况:

      a、可能是由于原集群中有一个新的服务器上线/重新启动,但是原来的已有集群的机器已经选主成功,因此,别无他法,只有加入原来的集群成为Follower。

      b、可能是因为某个节点出现了网络隔离导致其触发一次新的选主,然后系统中其他节点状态依然正常。发起选主的节点要递增其logical clock,则大于(网络隔离的老结点),

 

      如果对方节点处于FOLLOWING/LEADING状态,除检查是否过半外,同时还要检查leader是否给自己发送过投票信息,从投票信息中确认该leader是不是LEADING状态。

          该方案原因:此时leader和follower都需要各自检测是否进入leader选举过程。leader检测到未过半的server的ping回复,则leader会进入LOOKING状态;follower有自己的检测,感知这一事件,还需要一定时间;在此期间,如果其他server加入到该集群,可能会收到其他follower的过半的对之前leader的投票,但是此时该leader已经不处于LEADING状态了,所以需要这么一个检查来排除这种情况。

 

posted @ 2022-04-12 11:34  修心而结网  阅读(186)  评论(0编辑  收藏  举报