• Zookeeper之跟着zk学习怎么写阻塞至过半投票


      zookeeper中有很多逻辑是等到超过一半选票才能继续的场景。来看看怎么实现的吧

      Leader.getEpochToPropose

      在选出来主之后,会进入到这个分支

      QuorumPeer#

    case LEADING:
                        LOG.info("LEADING");
                        try {
                            setLeader(makeLeader(logFactory));
                            leader.lead();
                            setLeader(null);
                        } catch (Exception e) {
                            LOG.warn("Unexpected exception", e);
                        } finally {
                            if (leader != null) {
                                leader.shutdown("Forcing shutdown");
                                setLeader(null);
                            }
                            updateServerState();
                        }
                        break;
                    }

      同时,follower也会进入自己的follow分支,简单说下逻辑,就是和leader建立通信,然后发送消息,表示要和leader进行数据同步。

      消息类型为 Leader.FOLLOWERINFO

      这里忽略leader的网络通信部分逻辑。直接看获取epoch的逻辑。

      protected final Set<Long> connectingFollowers = new HashSet<Long>();

    public long getEpochToPropose(long sid, long lastAcceptedEpoch) throws InterruptedException, IOException {
            synchronized (connectingFollowers) {
                if (!waitingForNewEpoch) {
                    return epoch;
                }
                if (lastAcceptedEpoch >= epoch) {//找followe传过来的epoch最大值然后 +1
                    epoch = lastAcceptedEpoch + 1;
                }
                if (isParticipant(sid)) {
                    connectingFollowers.add(sid);
                }
                QuorumVerifier verifier = self.getQuorumVerifier();
                if (connectingFollowers.contains(self.getId()) && verifier.containsQuorum(connectingFollowers)) {//超过一半了
                    waitingForNewEpoch = false;//这里改为false 下面的while就会跳出了
                    self.setAcceptedEpoch(epoch);
                    connectingFollowers.notifyAll();//唤醒阻塞
                } else {
                    long start = Time.currentElapsedTime();
                    if (sid == self.getId()) {
                        timeStartWaitForEpoch = start;
                    }
                    long cur = start;
                    long end = start + self.getInitLimit() * self.getTickTime();
                    while (waitingForNewEpoch && cur < end && !quitWaitForEpoch) {
                        connectingFollowers.wait(end - cur);
                        cur = Time.currentElapsedTime();
                    }
                    if (waitingForNewEpoch) {
                        throw new InterruptedException("Timeout while waiting for epoch from quorum");
                    }
                }
                return epoch;
            }
        }

      QuorumVerifier 可以简单地理解就是比较是否大于集群服务器数量的一半的工具类

      

      向connectionFollowers中添加记录的逻辑在LearnerHandler

      不断地收到follower发过来的请求,慢慢的就满足了半数条件了

    @Override
        public void run() {
            try {
                ......long newEpoch = learnerMaster.getEpochToPropose(this.getSid(), lastAcceptedEpoch);//不断向connectionFollowers中增加元素
  • 相关阅读:
    day3
    day2
    day1-存储
    day5-iptables
    MySQL之补充
    11.18
    11.17
    junit基础学习之-测试controller层(2)
    junit基础学习之-简介(1)
    外键和级联
  • 原文地址:https://www.cnblogs.com/juniorMa/p/15475989.html
Copyright © 2020-2023  润新知