zoukankan      html  css  js  c++  java
  • ZOOKEEPER3.3.3源码分析(四)对LEADER选举过程分析的纠正

    很抱歉,之前分析的zookeeper leader选举算法有误,特此更正说明.

    那里面最大的错误在于,leader选举其实不是在大多数节点通过就能选举上的,这一点与传统的paxos算法不同,因为如果这样的话,就会出现数据丢失的情况.比如某台服务器其实有最多的数据量,按照规则而言应该是leader,但是由于启动晚了,最后只能把leader让给其它的服务器.这里面存在明显的时序问题,也就是说leader服务器启动的早晚会影响整个过程.

    实际上并不是这样,leader选举算法只有在收到所有参与服务器的回复才能结束.代码如下:

                            /*
                             * Only proceed if the vote comes from a replica in the
                             * voting view.
                             */
                            if(self.getVotingView().containsKey(n.sid)){
                                recvset.put(n.sid, new Vote(n.leader, n.zxid, n.epoch));
    
                                //If have received from all nodes, then terminate
                                if ((self.getVotingView().size() == recvset.size()) &&
                                        (self.getQuorumVerifier().getWeight(proposedLeader) != 0)){
                                    self.setPeerState((proposedLeader == self.getId()) ?
                                            ServerState.LEADING: learningState());
                                    leaveInstance();
                                    return new Vote(proposedLeader, proposedZxid);
    
                                } else if (termPredicate(recvset,
                                        new Vote(proposedLeader, proposedZxid,
                                                logicalclock))) {
    
                                    // Verify if there is any change in the proposed leader
                                    while((n = recvqueue.poll(finalizeWait,
                                            TimeUnit.MILLISECONDS)) != null){
                                        if(totalOrderPredicate(n.leader, n.zxid,
                                                proposedLeader, proposedZxid)){
                                            recvqueue.put(n);
                                            break;
                                        }
                                    }
    
                                    /*
                                     * This predicate is true once we don't read any new
                                     * relevant message from the reception queue
                                     */
                                    if (n == null) {
                                        self.setPeerState((proposedLeader == self.getId()) ?
                                                ServerState.LEADING: learningState());
                                        if(LOG.isDebugEnabled()){
                                            LOG.debug("About to leave FLE instance: Leader= "
                                                + proposedLeader + ", Zxid = " +
                                                proposedZxid + ", My id = " + self.getId()
                                                + ", My state = " + self.getPeerState());
                                        }
    
                                        leaveInstance();
                                        return new Vote(proposedLeader,
                                                proposedZxid);
                                    }
                                }
                            }
    

    简单的说,以上的代码分为两种情况进行处理:
    1) 如果已经接收到所有服务器的封包(self.getVotingView().size() == recvset.size()),那么这台服务器选举的leader就定下来了.
    2) 否则如果这个leader已经得到超过半数的服务器认同(函数termPredicate),那么当前线程将被阻塞等待一段时间(这个时间在finalizeWait定义)看看是不是还有其它服务器比当前leader更优的leader,如果经过一段时间还没有这个新的leader提出来,同样也是选举这个leader了,否则进行下一次选举.

    对于过程2)我有一个疑问,同样是时序问题,如果那个真正的leader在这个时间点到来之前还没有启动,岂不是又成不了leader了?好吧,如果换了我的设计,应该全部走过程1),即在收到所有服务器的封包才做出决定,而如果在一段时间内没有收集起来所有的服务器封包,干脆退出好了.理由:干脆的死或者干脆的活比起半死不活总是好些的.

  • 相关阅读:
    2019-8-22学习笔记---文件上传与读取
    JS字符串的操作
    JS控制台打印星星,总有你要的那一款~呐~给你小心心哦~~~❤
    DOM的操作(增删改查)
    js上传视频(jquery.form.js)
    vue单页面模板说明文档(3)
    vue单页面模板说明文档(2)
    vue单页面模板说明文档(1)
    js 通过url获取里面的参数值
    ios点击输入框,界面放大解决方案
  • 原文地址:https://www.cnblogs.com/hadoop-dev/p/5946872.html
Copyright © 2011-2022 走看看