一、zookeeper选主逻辑主要是根据投票数来定的,具体的逻辑如下:
判断依据:
1、Epoch:leader的任期,任期大的优先级高,其他的节点优先投票给任期大的节点
2、ZXID:zookeeper事务ID,越大表示数据越新,在任期相同时则比较zxid
3、SID:集群中每个节点的唯一编号,当任期、事务id都相同的时候则比较该值,sid越大的优先获得其他节点的投票
二:zookeeper选主源代码分析:
public Vote lookForLeader() throws InterruptedException
选主的入口主要是集中在这儿:
synchronized (this) {
logicalclock.incrementAndGet();
updateProposal(getInitId(), getInitLastLoggedZxid(), getPeerEpoch());
}
其中 logicalclock 表示选举轮数,每一次选举该值都会增加,表示选举轮数增加。我们跟踪进 在这里updateProposal(getInitId(), getInitLastLoggedZxid(), getPeerEpoch());插入代码片
方法去看一下:
synchronized void updateProposal(long leader, long zxid, long epoch) {
LOG.debug(
"Updating proposal: {} (newleader), 0x{} (newzxid), {} (oldleader), 0x{} (oldzxid)",
leader,
Long.toHexString(zxid),
proposedLeader,
Long.toHexString(proposedZxid));
proposedLeader = leader;
proposedZxid = zxid;
proposedEpoch = epoch;
}
可以看到,当投票开始的时候,这里所作的操作就是初始化选举信息,
具体的投票操作是在 sendNotifications();
这里所作的操作就是将自己的选举票发送给自己将要选举的节点,其代码如下:
private void sendNotifications() {
for (long sid : self.getCurrentAndNextConfigVoters()) {
QuorumVerifier qv = self.getQuorumVerifier();
ToSend notmsg = new ToSend(
ToSend.mType