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;
}
}
- 若是當前server.myId等於選舉出的leader的myId——也就是proposedLeader,則當前server就是leader,設置peerState爲ServerState.LEADING
- 不然判斷當前server的具體角色,由於follower和observer都是learner,須要根據各自的配置來決定該server的狀態(配置文件裏面的key是peerType,可選的值是participant、observer,若是不配置learnerType默認是LearnerType.PARTICIPANT)
- 若是配置的learnerType是LearnerType.PARTICIPANT,則狀態爲ServerState.FOLLOWING
- 不然,狀態爲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,具有通訊狀態同步
- leader阻塞等待follower發來的第一個packet
- 校驗packet類型是不是Leader.FOLLOWERINFO或者Leader.OBSERVERINFO
- 讀取learner信息
- sid
- protocolVersion
- 校驗follower的version不能比leader的version還要新
- leader發送packet(Leader.LEADERINFO)給follower
- follower收到Leader.LEADERINFO後給leader回覆Leader.ACKEPOCH
- leader根據follower ack的packet內容來決定同步的策略
- lastProcessedZxid == peerLastZxid,leader的zxid和follower的相同
- peerLastZxid > maxCommittedLog && !isPeerNewEpochZxid follower超前,刪除follower多出的txlog部分
- (maxCommittedLog >= peerLastZxid) && (minCommittedLog <= peerLastZxid) follower落後於leader,處於leader的中間 同步(peerLaxtZxid, maxZxid]之間的commitlog給follower
- peerLastZxid < minCommittedLog && txnLogSyncEnabled follower落後於leader,使用txlog和commitlog同步給follower
- 接下來leader會不斷的發送packet給follower,follower處理leader發來的每一個packet
- 同步完成後follower回覆ack給leader
- leader、follower進入正式處理客戶端請求的while循環
總結
zookeeper爲了保證啓動後leader和follower的數據一致,在啓動的時候就進行數據同步,leader與follower數據傳輸的端口和leader選舉的端口不同。數據同步完成後就能夠接受client的請求進行處理了。it