zooKeeper leader选举

zooKeeper leader选举

  • 1.所有server处于looking状态,则进行交流选举一个leader,具体做法是某个server向其他节点发送通知信息(vote),该信息包含两个部分:当前server的sid以及该server的最大zxid(包含epoch和自增计数器)。
  1. 例如有选票A(voteId表示sid,voteZxid表示它的最大事务id),节点B此时的sid为myId,zxid为myZxid。
  1. 若(voteZxid > myZxid) 或者(voteZxid = myZxid and voteId > mySid),则B保留A选票
  2. 另外一方面, B将自己的选票的(mySid,myZxid)改为(voteId,voteZxid)
  3. 若某个server收到法定数量的相同选票,则宣布leader选举产生了,若leader正好是该server,则履行领导角色;否则,它就变成follower,然后尝试联系leader,若联系上了,则同步状态,完成同步以后才能接受新的请求
  • 2.选出leader,则该节点进入leading状态,其他server进入following状态
  • 3.leader发送“领导选举通知”

举例

zooKeeper leader选举_第1张图片

  • s1,s2,s3同时发送自己的选票
  • s2,s3发现s1的选票(1,6)最大,则把各自修改选票为(1,6),并再次发送
  • s2,s3,s1均收到了s1最大的选票,达到法定数量,s1选举为leader

异常情况

问题描述

  • 对于网络环境较差的情况,可能导致某些server发生错误选举的情况。例如如下所示
    zooKeeper leader选举_第2张图片

  • 1.s1,s2,s3发送自己的选票

  • 2.由于s1–>s2网络延迟,导致s2未能立马收到s1的选票

  • 3.s2收到s3的选票,修改自己的选票为(3,5),并选择s3为leader

  • 4.由于s3已经收到了s1的选票(1,6),并修改了自己的选票。此时它收到s2的选票,选举它为leader(显然这是错误的),因此s3不会给s2返回信息

  • 5.由于s2未收到s3的反馈信息,则进行重试,重试期间不会处理任何client发送过来的请求

解决办法

  • 造成上述情况的原因是,s2过早的进行了选举,如果它等待一段时间,那么就会收到s1发来的选票信息,就不会去选s3作为leader。因此,可以设置一个固定的等待时间,默认FastLeaderElection,为200ms,如下图所示,红色部分表示s2进行选举
    zooKeeper leader选举_第3张图片
  • 如果设置了等待时间,网络非常差,依旧导致上述情况发生,由于选择s3作为leader的sever数量没有达到法定的数量(2个),则s2需要进行重新进行选举。期间浪费了不必要的状态同步(s2–>s3),影响整个系统的性能。

你可能感兴趣的:(Java,分布式)