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.不做任何处理。