1. 程式人生 > >zookeeper源碼分析:選舉流程和請求處理

zookeeper源碼分析:選舉流程和請求處理

and ces 成員 star sse rep gpo 方法 nec

集群啟動:

  1. QuorumPeerMain. runFromConfig()
  2. quorumPeer.start();
    • loadDataBase();
    • cnxnFactory.start(); //網絡通信交互
    • startLeaderElection();//啟動選舉類
    • super.start();
  3. quorumPeer.run()
    • case LOOKING:   
      • new ReadOnlyZooKeeperServer()   //選舉期間啟用只讀服務器,
      • FastLeaderElection.start()  //設置啟動投票的後臺線程
      • setCurrentVote(makeLEStrategy().lookForLeader()); while循環
    • case LEADING: new LeaderZooKeeperServer().lead();

case LOOKING:快速選舉

  1. FastLeaderElection.start()
    • sendqueue = new LinkedBlockingQueue<ToSend>();//發出的投票隊列
    • recvqueue = new LinkedBlockingQueue<Notification>();//收到的投票對列
    • this.messenger = new Messenger(manager);//投票消息後臺服務線程
      • new WorkerSender(manager); //開啟投票的發送線程
      • new WorkerReceiver(manager);//開啟投票的接收線程
  2. FastLeaderElection.lookForLeader():
    • sendNotifications
    • 比較epoch
    • totalOrderPredicate//對兩個投票進行比較,規則是:選舉期數 > zxid > serverid
    • recvset.put(n.sid, new Vote(n.leader, n.zxid, n.electionEpoch, n.peerEpoch));/收集選票
    • termPredicate//判斷是否已經選出leader
  3. case LEADING: termPredicate
  4. ReadOnlyZooKeeperServer.startup()
    • Zookeeper.startup
    • createSessionTracker();//session管理類
    • setupRequestProcessors();//子類重寫的方法,設置request處理責任鏈

case LEADING:

請求處理

  1. NIOServerCnxnFactory.start()
  2. setupRequestProcessors
    1. PrepRequestProcessor
    2. ProposalRequestProcessor
    3. CommitProcessor
    4. ToBeAppliedRequestProcessor
    5. FinalRequestProcessor
  3. ProposalRequestProcessor.run()
    1. LearnerHandler.run();//leader初始化的時候,每accept一個connection,就會生成一個follower專門的LearnerHandler用於處理事務
    2. CommitProcessor.processRequest(request);// LinkedList queuedRequests,是已經發出的提議,要等待收到過半服務器ack的請求隊列
    3. Leader.propose(request);//向所有的folllower發送提案
    4. Leader.processAck(this.sid, qp.getZxid(), sock.getLocalSocketAddress());
    5. p.ackSet.add(sid); //對於一個特定的提案,每個follower反饋的ACK信息
    6. if (self.getQuorumVerifier().containsQuorum(p.ackSet)){ //超過半數

toBeApplied.add(p);//用於? ToBeAppliedRequestProcessor處理

commit(zxid);//提交給集群中所有成員

zk.commitProcessor.commit(p.request);//提交給commitProcessor處理,LinkedList committedRequests,是已經收到過半服務器ack的請求隊列,以為著該請求可以被提交了。

}

4. CommitProcessor.run();//匹配queuedRequests和committedRequests中的請求,並交給nextProcessor處理。

5. ToBeAppliedRequestProcessor.processRequest(request);//交給nextProcessor處理,如果toBeApplied中的第一個元素與request的zxid相等,則可以移除toBeApplied隊首元素

zookeeper源碼分析:選舉流程和請求處理