zk的选取过程分析
- zk节点的类型
- Leader
- follower
- observer
zk在分布式系统的环境下,各节点启动时会通过paxos算法选举产生leader节点。选举leader的标准是当有超过一半的节点选举某个节点时,该节点即被选为leader节点。
选举过程如下:
1) 节点启动时,会向所有的节点包括自己发送Vote信息,包括选举的leader,zxid等信息,刚开始启动时会选举自己。
2) 当节点接收到集群中其它几点发过来的选举信息时,会采用如下算法判断是否需要重新发送选举信息。
条件:
/*
* We return true if one of the following three cases hold:
* 1- New epoch is higher
* 2- New epoch is the same as current epoch, but new zxid is higher
* 3- New epoch is the same as current epoch, new zxid is the same
* as current zxid, but server id is higher.
*/
return ((newEpoch > curEpoch) ||
((newEpoch == curEpoch) &&
((newZxid > curZxid) || ((newZxid == curZxid) && (newId > curId)))));
3)如果2)条件成立,则节点更新发送的选举信息为新收到的选举信息,并重新发送。如下所示:
if (totalOrderPredicate(n.leader, n.zxid, n.peerEpoch,
proposedLeader, proposedZxid, proposedEpoch)) {
updateProposal(n.leader, n.zxid, n.peerEpoch); //更新选举消息信息
sendNotifications(); //重新发送选举消息
}
4)将选举消息放到选举的接收集合中。
recvset.put(n.sid, new Vote(n.leader, n.zxid, n.electionEpoch, n.peerEpoch)); //以发送选举消息的节点的sid为key,一个节点只能接收来自另外一个节点一个选举Vote
5)遍历选举的接收集合判断是否有一半的节点选举自己为leader,如果是,选举过程结束。
termPredicate(recvset, new Vote(proposedLeader, proposedZxid,
logicalclock.get(), proposedEpoch))
下图为两个节点情况下的选举。
三个节点情况下的选举如下所示: