Zookeeper原理篇-Zookeeper啓動流程分析

前言

上篇我們通過了解Paoxs算法開始,到Zab協議的兩大特性:崩潰恢復消息廣播,學習了Zookeeper是如何通過Zab協議實現高可用,本篇開始我們來學習Zookeeper的啓動流程

單機模式啓動流程

我們知道,Zookeeper使用中分爲單機和集羣兩種,而這兩種最大的不同則是,集羣啓動下需要進行Leader選舉以及Leader和Follower之間的數據同步操作,而單機啓動則不需要此操作,Zookeeper單機啓動大概分爲三個部分,分別爲預處理初始化註冊,接下來我們分別來看看三個流程的步驟

預處理

預處理操作中,將創建服務實例之前需要的數據讀取加載準備就緒,大體流程如下:

1.首先我們在使用zkServer.sh或者zkServer.cmd這兩個腳本啓動Zookeeper的時候,默認會啓動 org.apache.zookeeper.server.quorum.QuorumPeerMain類,因此無論是Zookeeper的單機還是集羣環境下, QuormPeerMain類都是作爲默認的入口啓動類啓動。

2.啓動後就會開始解析Zoo.cfg配置文件,從中讀取默認配置的tickTimedataDirclientPort

3.當配置讀取並解析完畢以後,會創建 DatadirCleanupManager類實例,此類是Zookeeper從3.4版本開始加入的對歷史記錄文件進行清理以及定時清理日誌和快照的管理器

4.從剛剛讀取解析的Zoo.cfg配置文件內容中找到clientPort參數內容,通過配置的地址判斷是否存在多個地址來確定當前啓動的模式是單機版還是集羣模式,如果當前啓動模式爲單機模式,將進入單機的啓動流程,並且讀取Zoo.cfg剩餘的配置信息

5.通過解析Zoo.cfg中的配置信息相關的參數,開始創建ZookeeperServer類實例,完成了這一步後,預處理階段完成

初始化

初始化階段,則是開始將Zookeeper中的相關服務管理類進行創建,大體流程如下:

1.創建了ZookeeperServer實例後,Zookeeper會創建一個ServerStats實例,此類用來收集Zookeeper運行過程中的統計信息,例如發送客戶端的響應包次數,收到的請求包次數,最近啓動後最大的延遲和最小延遲等

2.緊接着會創建Zookeeper中的數據存儲管理器--FileTxnSnaplog類,此類作爲最上層的,提供了一系列了操作數據文件的接口,其中包括操作事務日誌和操作快照的接口,而創建當前類實例會根據zoo.cfg中的dataDir以及dataLogDir參數進行構建

3.同樣根據解析出來的zoo.cfg配置文件中的tickTime以及session的會話時間來設置對應參數,並且會根據zookeeper.serverCnxnFactory參數來確定啓動Zookeeper的網絡連接工廠是基於Netty的還是基於jdk自身的Nio工廠

4.確定工廠類型後,Zookeeper會開始初始化一個Thread,作爲整個Zookeeper運行過程中的主線程,並且開始初始化ServerCnxnFactory實例

5.當ServerCnxnFactory實例構建完畢後,開始運行對應的run方法中的業務邏輯,此時由於連接工廠已經創建,端口其實已經對外開放了,但是Zookeeper此時還未完成啓動過程,還無法對外處理請求

6.開始恢復Zookeeper的數據,將從事務日誌以及之前保存的快照進行數據恢復

7.數據恢復完成後,Zookeeper開始構建會話管理器--SessionTracker,此類主要負責管理Session,在創建的時候,將e xpirationlntervalnextExpirationTime和 sessionsWithTimeout進行計算以及配置,並且會計算出每一個Session對應的SessionID,並且在運行過程中會負責Session的會話超時檢測等

8.創建完畢後,Zookeeper會初始化對應的請求過濾鏈,而在Zookeeper中請求的過濾鏈使用了責任鏈模式,其中處理的順序流程主要是PrepRequestProessor->SyncRequestProessor->FinalRequestProessor三個請求處理器,至此Zookeeper的初始化流程已經做完

註冊提供服務

當Zookeeper的初始化流程完成後,服務器已經開始到就緒狀態了,只需要將對應的信息註冊以後即可對外提供服務了,此階段的流程大概如下:

可以看到此階段中,Zookeeper只需要將JMX服務註冊,以及當前相關實例註冊完畢,即可完成單機啓動流程,此時的Zookeeper已經正常提供服務了

集羣模式啓動流程

集羣模式的啓動過程很多和單機模式是一樣的,但是由於集羣模式下,會有Leader機器選舉以及數據同步的過程,因此Zookeeper的集羣模式啓動過程要複雜的多,而整個集羣的啓動過程,大體可以分爲五個部分,分別是預處理初始化Leader選舉Leader與Follower交互以及Leader與Follower啓動,其中預處理過程幾乎與單機模式一樣,唯一的區別在於解析zoo.cfg中的連接配置,判斷啓動模式爲集羣模式,開始進入集羣模式的初始化操作流程而已,因此,我們從集羣模式的初始化開始

初始化

初始化過程大體和單機模式差不多,如下:

1.創建並初始化ServerCnxnFactory

2.創建Zookeeper中的數據文件管理器FileTxnSnaplog

3.在集羣模式下,會去創建QuorumPeer實例,Quorum是集羣模式下特有的對象,屬於Zookeeper的託管者,此類的作用是在運行期間,會不停的檢測當前服務器實例的狀態,並且在需要選舉的時候發起選舉

4.創建Zookeeper中的內存數據庫ZKDatabase實例,用來記錄會話記錄以及DataTree和事物日誌

5.QuorumPeer實例作爲託管者,會在啓動過程中,將核心組件信息註冊上去,包括之前創建的ZKDatabase、FileTxnSnaplog以及服務器列表信息,選舉算法等

6.開始恢復數據

7.數據恢復完成後,開始啓動ServerCnxnFactory中的主線程,運行run方法,開始執行服務器選舉相關的操作

Leader選舉

選舉階段的流程大概如下:

1.Zookeeper解析zoo.cfg配置文件中的 electionAlg屬性,來確定進行選舉的算法是哪一種,在Zk中有三種選舉算法,分別是 LeaderElection 、 AuthFastLeaderElection 和FastLeaderElection,分別對應數值0-3,不過從3.4的版本開始,zk僅支持FastLeaderElection選舉算法,其他兩種被廢棄了。同樣的,在選舉的初始化階段,zk會根據自身服務器ID、lastLoggedZxid和當前服務器的epoch初始化一個選舉的票據

2.選舉初始化準備好以後,開始註冊JMX服務

3.前面創建好的QuorumPeer實例會不斷檢測當前的服務器狀態,在正常情況下,QuorumPeer的狀態應該是LOOKING,纔會開始進行選舉操作

4.開始進行選舉操作,簡單來說,zk中一般是ZXID最大的機器成爲Leader,如果ZXID一樣,SID越大的則成爲Leader。(zk的詳細選舉流程,則在後續的文章中分析)

Leader與Follower交互

當選舉出Leader機器以後,其他的機器則會開始與Leader進行交互,進行數據同步等操作,此階段的流程大致如下:

1.不同角色(Leader和Follower)的zookeeper服務器在選舉完畢後,會開始進入各自角色的主流程

2.在Zookeeper集羣運行期間,Leader服務器需要和其他的服務器保持連接確定集羣的機器存活情況,zk創建LearnerCnxAcceptor實例用來負責處理所有的非Leader機器的連接請求

3.非Leader服務器在啓動完畢後,會從選舉的結果中找到集羣的Leader,並且嘗試進行連接

4.Leader的LearnerCnxAcceptor實例在接受到非Leader機器的請求後,會創建LearnerCnxHandler實例,每個實例會對應一個Leader與非Leader機器的連接,負責對應服務器之間的消息通信處理以及數據同步操作

5.當非Leader機器與Leader服務器建立連接後,非Leader機器就會將自己的信息發送給Leader,此過程的數據稱之爲LearnerInfo,其中包括了當前服務器的SID以及最大的ZXID

6.Leader收到LearnerInfo消息後,從中解析出SID和ZXID,然後根據ZXID解析出epochoflearner,和Leader自身的epochofleader進行比較,如果發現Leader的epochofleader比較小,則會更新Leader的epoch:

1.  `epoch_of_leader =  epoch_of_learner + 1`

然後繼續等待其他機器的LearnerInfo消息,直到半數以上,即可確定整個集羣中的epoch值了

7.在確定了epoch以後,Leader將該信息發送給所有的非Leader機器,此消息稱之爲LEADERINFO

8.Follower機器在收到Leader發送的LEADERINFO消息後,解析出消息中的epochZXID,然後響應給Leader一個ack

9.Leader收到ack以後,就可以開始與該Follower機器進行數據同步過程了

10.整個集羣中如果超過半數的Follower機器完成了和Leader之間的數據同步過程,這個時候集羣實例就已經可以提前啓動對外提供服務

Leader和Follower啓動

集羣模式下的Zookeeper在完成了Leader與Follower服務器之間的交互流程後,也開始進入到了啓動註冊的階段,此階段和單機模式流程幾乎相同,首先是創建並且啓動會話管理器,然後初始化Zookeeper中的請求處理鏈,接着Zookeeper開始註冊JMX服務,當註冊完畢後,整個集羣的啓動完成,此時Zookeeper的集羣也可以對外開始提供服務了f

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章