FastLeaderElection. lookForLeader():

1、  logicalclock++,表示是新一轮leader选举,它是一个内存值,服务器重启就会导致该值归0,所以如果服务器活得越久,这个值随着应该越大,每一轮选举会保持所有机器该值始终是其中相同的最大值。

2、  推举自己作为leader,并将自己服务器上存储的最大zxid,自己的服务器id,自己的状态(looking)notify所有的服务器,告知大家我想当leader.

3、  等待其他服务器的反馈消息,如果有消息回来,分为以下几个情况:

a)        自己还在looking,该消息标记的服务器也在looking

                               i.             消息的epoch<自己的logicalclock,表示这条消息是前面一轮的消息,于是回发一条消息告诉对方当前的机器的logicalclock和推举的leader和zxid

                             ii.             消息epoch>自己的logicalclock,表示对方已经开始新一轮选举了,更新logicalclock为epoch,清空接收到的所有服务器状态recvset.对比消息的zxid和本地的lastzxid,选取最大的作为leader,如果相同,则选取serverid最大的作为leader.然后sendNotifications()通知所有服务器我的选择。

                            iii.             消息epoch=自己的logicalclock,表示是同一轮选举,对比消息的zxid和本地的lastzxid,选取最大的作为leader,如果相同,则选取serverid最大的作为leader.如果返回的消息是最后选择,则sendNotifications()通知所有服务器我的选择,否则不理睬这条消息,不发送任何回应。

经过上面的选择之后,

1、  如果收集到了所有服务器的投票,

2、  如果此时收集的投票大于1/2服务器数,那么再等待一个时段,如果没有其他响应到来或者到来的响应没有新的选票产生。

此时看下此时选举出来的proposedLeader是否是自己,是则更改自己的状态为leading,否则更改为following,然后跳出选举阶段.

         如果不满足上面的两条条件,则继续等待消息。

b)        自己还在looking,该消息标记的服务器已经没有looking了

                               i.             消息的epoch=自己的logicalclock,如果消息状态是leading,那么就认为他是leading,更改自己的状态返回。如果消息认为自己是leader,那么需要有1/2以上服务器认为自己是leader,就更改状态并返回。

                             ii.             消息的epoch<>自己的logicalclock,那么投票将加入到outofelection中,如果有1/2服务器以上的投票选择这条消息推荐的leader,那么更改自身的状态并返回。

c)        自己没有looking,该消息标记的服务器还在looking

                               i.             获得当前的leader信息,直接通知对方已经选择的leader.

d)        自己没有looking,该消息标记的服务器没有looking

                               i.             不做任何处理。


Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐