Zookeeper Leader选举 源码中,发送投票,统计投票的不解
文章目录问题解决问题termPredicate这里判断投票是否结束if (termPredicate(recvset,new Vote(proposedLeader, proposedZxid,logicalclock.get(), propo...
问题
termPredicate这里判断投票是否结束
if (termPredicate(recvset,
new Vote(proposedLeader, proposedZxid,
logicalclock.get(), proposedEpoch)))
FastLeaderElection.termPredicate()
protected boolean termPredicate(
HashMap<Long, Vote> votes,
Vote vote) {
HashSet<Long> set = new HashSet<Long>();
/*
* First make the views consistent. Sometimes peers will have
* different zxids for a server depending on timing.
*
*/
//遍历接收到的所有选票数据
for (Map.Entry<Long,Vote> entry : votes.entrySet()) {
//对选票进行归纳,就是把所有选票数据中和当前节点的票据相同的票据进行统计
if (vote.equals(entry.getValue())){ //对票据进行归纳
set.add(entry.getKey()); //如果存在2票,set里面是不是有2个?
}
}//对选票进行判断
//进入containsQuorum 看QuorumMaj
//判断当前节点的票数是否是大于一半,默认采用 QuorumMaj 来实现
return self.getQuorumVerifier().containsQuorum(set); //验证
}
进入QuorumMaj.containsQuorum()
public boolean containsQuorum(Set<Long> set){
//这个 half 的值是多少呢?,也就是说,在构建 QuorumMaj 的时候,传递了当前集群节点的数量,这里是 3
// 那么, hafl=3/2=1 可以在 QuorumPeerConfig.parseProperties 这个方法中,找到如下代码。
//那么 set.size()>1. 意味着至少要有两个节点的票据是选择你当 leader,否则,还得继续投
return (set.size() > half); //已经归纳的票据是否大于half .2>1 -> leader选举、 数据同步
}
那么问题来了,上面的set是保存的是本地读到的投票,那么根据我的理解是不包括自己的投票的,这样的话,set.size()>half set.size()最小是half+1,即servers/2+1,算上本身自己的,也就是当前集群中是servers/2+2的时候表示投票结束?这显然跟众所周知的理论是不一样的,应该是算上自己的票,票数为servers/2+1的时候投票结束。
统计投票信息:server3统计收到的投票(包括自己投的),(1, 123)是两票,server1统计收到的投票(包括自己投的),(1, 123)是两票;
https://tech.souyunku.com/?p=6308
可以看到包括自己投的。
那究竟是为什么呢?
解决
首先,因为还没有看通信部分,所以产生了盲区
因为前面发送投票信息的时候是向集群所有节点发送,所以
当然也包括自己这个节点
,所以QuorumCnxManager的发送逻辑里会判断,如果这个要发送的投票信息是发送给自己的,则不发送了,直接进入接收队列。
https://www.itcodemonkey.com/article/4644.html
将变更的投票发给集群中所有的Follower节点。server.1将(10, 1)发给集群中
所有Follower,包括它自己
https://zhuanlan.zhihu.com/p/60083015
sendNotifications(); //
发送投票,包括发送给自己
https://blog.csdn.net/Dongguabai/article/details/82961284
选举的方法中刚开始和本地票发生变化的时候都会执行sendNotifications()方法将本地的票发送出去,这了包括发送给自己
所以上面的set是从 Notification n = recvqueue.poll(notTimeout, TimeUnit.MILLISECONDS);
中取的,但是去除来的包含自己本身的票
所以判断投票结束的依据确实是n/2+1(包含自己
)
更多推荐
所有评论(0)