【分布式】Zookeeper服務端啟動


一、前言

  前面已經了解了Zookeeper會話相關知識點,接着來學習Zookeeper服務端相關細節。

二、服務端

  服務端整體架構如下

  Zookeeper服務器的啟動,大致可以分為以下五個步驟

  1. 配置文件解析。

  2. 初始化數據管理器。

  3. 初始化網絡I/O管理器。

  4. 數據恢復。

  5. 對外服務。

  2.1 單機版服務器啟動

  單機版服務器的啟動其流程圖如下

  上圖的過程可以分為預啟動初始化過程。

  1. 預啟動

    1. 統一由QuorumPeerMain作為啟動類。無論單機或集群,在zkServer.cmd和zkServer.sh中都配置了QuorumPeerMain作為啟動入口類。

    2. 解析配置文件zoo.cfg。zoo.cfg配置運行時的基本參數,如tickTime、dataDir、clientPort等參數。

    3. 創建並啟動歷史文件清理器DatadirCleanupManager。對事務日志和快照數據文件進行定時清理。

    4. 判斷當前是集群模式還是單機模式啟動。若是單機模式,則委托給ZooKeeperServerMain進行啟動。

    5. 再次進行配置文件zoo.cfg的解析。

    6. 創建服務器實例ZooKeeperServer。Zookeeper服務器首先會進行服務器實例的創建,然后對該服務器實例進行初始化,包括連接器、內存數據庫、請求處理器等組件的初始化。

  2. 初始化

    1. 創建服務器統計器ServerStats。ServerStats是Zookeeper服務器運行時的統計器。

    2. 創建Zookeeper數據管理器FileTxnSnapLog。FileTxnSnapLog是Zookeeper上層服務器和底層數據存儲之間的對接層,提供了一系列操作數據文件的接口,如事務日志文件和快照數據文件。Zookeeper根據zoo.cfg文件中解析出的快照數據目錄dataDir和事務日志目錄dataLogDir來創建FileTxnSnapLog。

    3. 設置服務器tickTime和會話超時時間限制。

    4. 創建ServerCnxnFactory。通過配置系統屬性zookeper.serverCnxnFactory來指定使用Zookeeper自己實現的NIO還是使用Netty框架作為Zookeeper服務端網絡連接工廠。

    5. 初始化ServerCnxnFactory。Zookeeper會初始化Thread作為ServerCnxnFactory的主線程,然后再初始化NIO服務器。

    6. 啟動ServerCnxnFactory主線程。進入Thread的run方法,此時服務端還不能處理客戶端請求。

    7. 恢復本地數據。啟動時,需要從本地快照數據文件和事務日志文件進行數據恢復。

    8. 創建並啟動會話管理器。Zookeeper會創建會話管理器SessionTracker進行會話管理。

    9. 初始化Zookeeper的請求處理鏈。Zookeeper請求處理方式為責任鏈模式的實現。會有多個請求處理器依次處理一個客戶端請求,在服務器啟動時,會將這些請求處理器串聯成一個請求處理鏈。

    10. 注冊JMX服務。Zookeeper會將服務器運行時的一些信息以JMX的方式暴露給外部。

    11. 注冊Zookeeper服務器實例。將Zookeeper服務器實例注冊給ServerCnxnFactory,之后Zookeeper就可以對外提供服務。

  至此,單機版的Zookeeper服務器啟動完畢。

  2.2 集群服務器啟動

  單機和集群服務器的啟動在很多地方是一致的,其流程圖如下

  上圖的過程可以分為預啟動、初始化、Leader選舉、Leader與Follower啟動期交互過程、Leader與Follower啟動等過程。

  1. 預啟動

    1. 統一由QuorumPeerMain作為啟動類。

    2. 解析配置文件zoo.cfg。

    3. 創建並啟動歷史文件清理器DatadirCleanupFactory。

    4. 判斷當前是集群模式還是單機模式的啟動。在集群模式中,在zoo.cfg文件中配置了多個服務器地址,可以選擇集群啟動。

  2. 初始化

    1. 創建ServerCnxnFactory。

    2. 初始化ServerCnxnFactory。

    3. 創建Zookeeper數據管理器FileTxnSnapLog。

    4. 創建QuorumPeer實例。Quorum是集群模式下特有的對象,是Zookeeper服務器實例(ZooKeeperServer)的托管者,QuorumPeer代表了集群中的一台機器,在運行期間,QuorumPeer會不斷檢測當前服務器實例的運行狀態,同時根據情況發起Leader選舉。

    5. 創建內存數據庫ZKDatabase。ZKDatabase負責管理ZooKeeper的所有會話記錄以及DataTree和事務日志的存儲。

    6. 初始化QuorumPeer。將核心組件如FileTxnSnapLog、ServerCnxnFactory、ZKDatabase注冊到QuorumPeer中,同時配置QuorumPeer的參數,如服務器列表地址、Leader選舉算法和會話超時時間限制等。

    7. 恢復本地數據。

    8. 啟動ServerCnxnFactory主線程。

  3. Leader選舉

    1. 初始化Leader選舉。集群模式特有,Zookeeper首先會根據自身的服務器ID(SID)、最新的ZXID(lastLoggedZxid)和當前的服務器epoch(currentEpoch)來生成一個初始化投票,在初始化過程中,每個服務器都會給自己投票。然后,根據zoo.cfg的配置,創建相應Leader選舉算法實現,Zookeeper提供了三種默認算法(LeaderElection、AuthFastLeaderElection、FastLeaderElection),可通過zoo.cfg中的electionAlg屬性來指定,但現只支持FastLeaderElection選舉算法。在初始化階段,Zookeeper會創建Leader選舉所需的網絡I/O層QuorumCnxManager,同時啟動對Leader選舉端口的監聽,等待集群中其他服務器創建連接。

    2. 注冊JMX服務。

    3. 檢測當前服務器狀態。運行期間,QuorumPeer會不斷檢測當前服務器狀態。在正常情況下,Zookeeper服務器的狀態在LOOKING、LEADING、FOLLOWING/OBSERVING之間進行切換。在啟動階段,QuorumPeer的初始狀態是LOOKING,因此開始進行Leader選舉。

    4. Leader選舉。通過投票確定Leader,其余機器稱為Follower和Observer。具體算法在后面會給出。

  4. Leader和Follower啟動期交互過程

    1. 創建Leader服務器和Follower服務器。完成Leader選舉后,每個服務器會根據自己服務器的角色創建相應的服務器實例,並進入各自角色的主流程。

    2. Leader服務器啟動Follower接收器LearnerCnxAcceptor。運行期間,Leader服務器需要和所有其余的服務器(統稱為Learner)保持連接以確集群的機器存活情況,LearnerCnxAcceptor負責接收所有非Leader服務器的連接請求。

    3. Leader服務器開始和Leader建立連接。所有Learner會找到Leader服務器,並與其建立連接。

    4. Leader服務器創建LearnerHandler。Leader接收到來自其他機器連接創建請求后,會創建一個LearnerHandler實例,每個LearnerHandler實例都對應一個Leader與Learner服務器之間的連接,其負責Leader和Learner服務器之間幾乎所有的消息通信和數據同步。

    5. 向Leader注冊。Learner完成和Leader的連接后,會向Leader進行注冊,即將Learner服務器的基本信息(LearnerInfo),包括SID和ZXID,發送給Leader服務器。

    6. Leader解析Learner信息,計算新的epoch。Leader接收到Learner服務器基本信息后,會解析出該Learner的SID和ZXID,然后根據ZXID解析出對應的epoch_of_learner,並和當前Leader服務器的epoch_of_leader進行比較,如果該Learner的epoch_of_learner更大,則更新Leader的epoch_of_leader = epoch_of_learner + 1。然后LearnHandler進行等待,直到過半Learner已經向Leader進行了注冊,同時更新了epoch_of_leader后,Leader就可以確定當前集群的epoch了。

    7. 發送Leader狀態。計算出新的epoch后,Leader會將該信息以一個LEADERINFO消息的形式發送給Learner,並等待Learner的響應。

    8. Learner發送ACK消息。Learner接收到LEADERINFO后,會解析出epoch和ZXID,然后向Leader反饋一個ACKEPOCH響應。

    9. 數據同步。Leader收到Learner的ACKEPOCH后,即可進行數據同步。

    10. 啟動Leader和Learner服務器。當有過半Learner已經完成了數據同步,那么Leader和Learner服務器實例就可以啟動了。

  5. Leader和Follower啟動

    1. 創建啟動會話管理器。

    2. 初始化Zookeeper請求處理鏈,集群模式的每個處理器也會在啟動階段串聯請求處理鏈。

    3. 注冊JMX服務。

  至此,集群版的Zookeeper服務器啟動完畢。

三、總結

  本篇博文分析了Zookeeper服務端的啟動的詳細細節,之后會給出具體的代碼分析。也謝謝各位園友的觀看~


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM