zookeeper源碼 — 3、集羣啓動—leader、follower同步

zookeeper集羣啓動的時候,首先讀取配置,接着開始選舉,選舉完成之後,每一個server根據選舉的結果設置本身的角色,角色設置完成後leader須要和全部的follower同步。上面一篇介紹了leader選舉過程,這篇接着介紹啓動過程當中的leader和follower同步過程。java

本文結構以下:code

  • 同步過程
  • 總結

同步過程

設置server當前狀態

server剛啓動的時候都處於LOOKING狀態,選舉完成後根據選舉結果和對應配置進入對應的狀態,設置狀態的方法是:server

private void setPeerState(long proposedLeader, SyncedLearnerTracker voteSet) {
    ServerState ss = (proposedLeader == self.getId()) ?
            ServerState.LEADING: learningState();
    self.setPeerState(ss);
    if (ss == ServerState.LEADING) {
        leadingVoteSet = voteSet;
    }
}
  1. 若是當前server.myId等於選舉出的leader的myId——也就是proposedLeader,則當前server就是leader,設置peerState爲ServerState.LEADING
  2. 不然判斷當前server的具體角色,由於follower和observer都是learner,須要根據各自的配置來決定該server的狀態(配置文件裏面的key是peerType,可選的值是participant、observer,若是不配置learnerType默認是LearnerType.PARTICIPANT)
    1. 若是配置的learnerType是LearnerType.PARTICIPANT,則狀態爲ServerState.FOLLOWING
    2. 不然,狀態爲ServerState.OBSERVING

準備同步

leader開始工做的入口就是leader.lead方法,這裏的leader是Leader的實例,以下圖所示blog

準備的過程是:ip

  • 建立leader的實例,Leader,構造方法中傳入LeaderZooKeeperServer的實例
  • 調用leader.lead
    • 加載ZKDatabase
    • 監聽指定的端口(配置的用來監聽learner鏈接請求的端口,配置的第一個冒號後的端口),接收來自follower的請求
    • while循環,檢查當前選舉的狀態是否發生變化須要從新進行選舉

同時,follower設置完本身的狀態後,也開始進行相似leader的工做ci

  • 建立follower,也就是Follower的實例,同時建立FollowerZooKeeperServer
  • 創建和leader的鏈接

進行同步

同步的整體過程以下:get

在準備階段完成follower鏈接到leader,具有通訊狀態同步

  1. leader阻塞等待follower發來的第一個packet
    1. 校驗packet類型是不是Leader.FOLLOWERINFO或者Leader.OBSERVERINFO
    2. 讀取learner信息
      1. sid
      2. protocolVersion
      3. 校驗follower的version不能比leader的version還要新
  2. leader發送packet(Leader.LEADERINFO)給follower
  3. follower收到Leader.LEADERINFO後給leader回覆Leader.ACKEPOCH
  4. leader根據follower ack的packet內容來決定同步的策略
    1. lastProcessedZxid == peerLastZxid,leader的zxid和follower的相同
    2. peerLastZxid > maxCommittedLog && !isPeerNewEpochZxid follower超前,刪除follower多出的txlog部分
    3. (maxCommittedLog >= peerLastZxid) && (minCommittedLog <= peerLastZxid) follower落後於leader,處於leader的中間 同步(peerLaxtZxid, maxZxid]之間的commitlog給follower
    4. peerLastZxid < minCommittedLog && txnLogSyncEnabled follower落後於leader,使用txlog和commitlog同步給follower
    5. 接下來leader會不斷的發送packet給follower,follower處理leader發來的每一個packet
  5. 同步完成後follower回覆ack給leader
  6. leader、follower進入正式處理客戶端請求的while循環

總結

zookeeper爲了保證啓動後leader和follower的數據一致,在啓動的時候就進行數據同步,leader與follower數據傳輸的端口和leader選舉的端口不同。數據同步完成後就能夠接受client的請求進行處理了。it

相關文章
相關標籤/搜索