Zookeeper簡介及核心概念

一、Zookeeper簡介

Zookeeper 是一個開源的分佈式協調服務,目前由 Apache 進行維護。Zookeeper 可以用於實現分佈式系統中常見的發佈/訂閱、負載均衡、命令服務、分佈式協調/通知、集羣管理、Master 選舉、分佈式鎖和分佈式隊列等功能。它具有以下特性:

  • 順序一致性:從一個客戶端發起的事務請求,最終都會嚴格按照其發起順序被應用到 Zookeeper 中;
  • 原子性:所有事務請求的處理結果在整個集羣中所有機器上都是一致的;不存在部分機器應用了該事務,而另一部分沒有應用的情況;
  • 單一視圖:所有客戶端看到的服務端數據模型都是一致的;
  • 可靠性:一旦服務端成功應用了一個事務,則其引起的改變會一直保留,直到被另外一個事務所更改;
  • 實時性:一旦一個事務被成功應用後,Zookeeper 可以保證客戶端立即可以讀取到這個事務變更後的最新狀態的數據。

二、Zookeeper設計目標

Zookeeper 致力於爲那些高吞吐的大型分佈式系統提供一個高性能、高可用、且具有嚴格順序訪問控制能力的分佈式協調服務。它具有以下四個目標:

2.1 目標一:簡單的數據模型

Zookeeper 通過樹形結構來存儲數據,它由一系列被稱爲 ZNode 的數據節點組成,類似於常見的文件系統。不過和常見的文件系統不同,Zookeeper 將數據全量存儲在內存中,以此來實現高吞吐,減少訪問延遲。
在這裏插入圖片描述

2.2 目標二:構建集羣

可以由一組 Zookeeper 服務構成 Zookeeper 集羣,集羣中每臺機器都會單獨在內存中維護自身的狀態,並且每臺機器之間都保持着通訊,只要集羣中有半數機器能夠正常工作,那麼整個集羣就可以正常提供服務。
在這裏插入圖片描述

2.3 目標三:順序訪問

對於來自客戶端的每個更新請求,Zookeeper 都會分配一個全局唯一的遞增 ID,這個 ID 反映了所有事務請求的先後順序。

2.4 目標四:高性能高可用

ZooKeeper 將數據存全量儲在內存中以保持高性能,並通過服務集羣來實現高可用,由於 Zookeeper 的所有更新和刪除都是基於事務的,所以其在讀多寫少的應用場景中有着很高的性能表現。

三、核心概念

3.1 集羣角色

Zookeeper 集羣中的機器分爲以下三種角色:

  • Leader :爲客戶端提供讀寫服務,並維護集羣狀態,它是由集羣選舉所產生的;
  • Follower :爲客戶端提供讀寫服務,並定期向 Leader 彙報自己的節點狀態。同時也參與寫操作“過半寫成功”的策略和 Leader 的選舉;
  • Observer :爲客戶端提供讀寫服務,並定期向 Leader 彙報自己的節點狀態,但不參與寫操作“過半寫成功”的策略和 Leader 的選舉,因此 Observer 可以在不影響寫性能的情況下提升集羣的讀性能。

3.2 會話

Zookeeper 客戶端通過 TCP 長連接連接到服務集羣,會話 (Session) 從第一次連接開始就已經建立,之後通過心跳檢測機制來保持有效的會話狀態。通過這個連接,客戶端可以發送請求並接收響應,同時也可以接收到 Watch 事件的通知。

關於會話中另外一個核心的概念是 sessionTimeOut(會話超時時間),當由於網絡故障或者客戶端主動斷開等原因,導致連接斷開,此時只要在會話超時時間之內重新建立連接,則之前創建的會話依然有效。

3.3 數據節點

Zookeeper 數據模型是由一系列基本數據單元 Znode(數據節點) 組成的節點樹,其中根節點爲 /。每個節點上都會保存自己的數據和節點信息。Zookeeper 中節點可以分爲兩大類:

  • 持久節點 :節點一旦創建,除非被主動刪除,否則一直存在;
  • 臨時節點 :一旦創建該節點的客戶端會話失效,則所有該客戶端創建的臨時節點都會被刪除。

臨時節點和持久節點都可以添加一個特殊的屬性:SEQUENTIAL,代表該節點是否具有遞增屬性。如果指定該屬性,那麼在這個節點創建時,Zookeeper 會自動在其節點名稱後面追加一個由父節點維護的遞增數字。

3.4 節點信息

每個 ZNode 節點在存儲數據的同時,都會維護一個叫做 Stat 的數據結構,裏面存儲了關於該節點的全部狀態信息。如下:

狀態屬性 說明
czxid 數據節點創建時的事務 ID
ctime 數據節點創建時的時間
mzxid 數據節點最後一次更新時的事務 ID
mtime 數據節點最後一次更新時的時間
pzxid 數據節點的子節點最後一次被修改時的事務 ID
cversion 子節點的更改次數
version 節點數據的更改次數
aversion 節點的 ACL 的更改次數
ephemeralOwner 如果節點是臨時節點,則表示創建該節點的會話的 SessionID;如果節點是持久節點,則該屬性值爲 0
dataLength 數據內容的長度
numChildren 數據節點當前的子節點個數

3.5 Watcher

Zookeeper 中一個常用的功能是 Watcher(事件監聽器),它允許用戶在指定節點上針對感興趣的事件註冊監聽,當事件發生時,監聽器會被觸發,並將事件信息推送到客戶端。該機制是 Zookeeper 實現分佈式協調服務的重要特性。

3.6 ACL

Zookeeper 採用 ACL(Access Control Lists) 策略來進行權限控制,類似於 UNIX 文件系統的權限控制。它定義瞭如下五種權限:

  • CREATE:允許創建子節點;
  • READ:允許從節點獲取數據並列出其子節點;
  • WRITE:允許爲節點設置數據;
  • DELETE:允許刪除子節點;
  • ADMIN:允許爲節點設置權限。

四、ZAB協議

4.1 ZAB協議與數據一致性

ZAB 協議是 Zookeeper 專門設計的一種支持崩潰恢復的原子廣播協議。通過該協議,Zookeeper 基於主從模式的系統架構來保持集羣中各個副本之間數據的一致性。具體如下:

Zookeeper 使用一個單一的主進程來接收並處理客戶端的所有事務請求,並採用原子廣播協議將數據狀態的變更以事務 Proposal 的形式廣播到所有的副本進程上去。如下圖:
在這裏插入圖片描述
具體流程如下:

所有的事務請求必須由唯一的 Leader 服務來處理,Leader 服務將事務請求轉換爲事務 Proposal,並將該 Proposal 分發給集羣中所有的 Follower 服務。如果有半數的 Follower 服務進行了正確的反饋,那麼 Leader 就會再次向所有的 Follower 發出 Commit 消息,要求將前一個 Proposal 進行提交。

4.2 ZAB協議的內容

ZAB 協議包括兩種基本的模式,分別是崩潰恢復和消息廣播:

  1. 崩潰恢復
    當整個服務框架在啓動過程中,或者當 Leader 服務器出現異常時,ZAB 協議就會進入恢復模式,通過過半選舉機制產生新的 Leader,之後其他機器將從新的 Leader 上同步狀態,當有過半機器完成狀態同步後,就退出恢復模式,進入消息廣播模式。

  2. 消息廣播
    ZAB 協議的消息廣播過程使用的是原子廣播協議。在整個消息的廣播過程中,Leader 服務器會每個事物請求生成對應的 Proposal,併爲其分配一個全局唯一的遞增的事務 ID(ZXID),之後再對其進行廣播。具體過程如下:

    Leader 服務會爲每一個 Follower 服務器分配一個單獨的隊列,然後將事務 Proposal 依次放入隊列中,並根據 FIFO(先進先出) 的策略進行消息發送。Follower 服務在接收到 Proposal 後,會將其以事務日誌的形式寫入本地磁盤中,並在寫入成功後反饋給 Leader 一個 Ack 響應。當 Leader 接收到超過半數 Follower 的 Ack 響應後,就會廣播一個 Commit 消息給所有的 Follower 以通知其進行事務提交,之後 Leader 自身也會完成對事務的提交。而每一個 Follower 則在接收到 Commit 消息後,完成事務的提交。
    在這裏插入圖片描述

五、Zookeeper的典型應用場景

5.1數據的發佈/訂閱

數據的發佈/訂閱系統,通常也用作配置中心。在分佈式系統中,你可能有成千上萬個服務節點,如果想要對所有服務的某項配置進行更改,由於數據節點過多,你不可逐臺進行修改,而應該在設計時採用統一的配置中心。之後發佈者只需要將新的配置發送到配置中心,所有服務節點即可自動下載並進行更新,從而實現配置的集中管理和動態更新。

Zookeeper 通過 Watcher 機制可以實現數據的發佈和訂閱。分佈式系統的所有的服務節點可以對某個 ZNode 註冊監聽,之後只需要將新的配置寫入該 ZNode,所有服務節點都會收到該事件。

5.2 命名服務

在分佈式系統中,通常需要一個全局唯一的名字,如生成全局唯一的訂單號等,Zookeeper 可以通過順序節點的特性來生成全局唯一 ID,從而可以對分佈式系統提供命名服務。

5.3 Master選舉

分佈式系統一個重要的模式就是主從模式 (Master/Salves),Zookeeper 可以用於該模式下的 Matser 選舉。可以讓所有服務節點去競爭性地創建同一個 ZNode,由於 Zookeeper 不能有路徑相同的 ZNode,必然只有一個服務節點能夠創建成功,這樣該服務節點就可以成爲 Master 節點。

5.4 分佈式鎖

可以通過 Zookeeper 的臨時節點和 Watcher 機制來實現分佈式鎖,這裏以排它鎖爲例進行說明:

分佈式系統的所有服務節點可以競爭性地去創建同一個臨時 ZNode,由於 Zookeeper 不能有路徑相同的 ZNode,必然只有一個服務節點能夠創建成功,此時可以認爲該節點獲得了鎖。其他沒有獲得鎖的服務節點通過在該 ZNode 上註冊監聽,從而當鎖釋放時再去競爭獲得鎖。鎖的釋放情況有以下兩種:

  • 當正常執行完業務邏輯後,客戶端主動將臨時 ZNode 刪除,此時鎖被釋放;
  • 當獲得鎖的客戶端發生宕機時,臨時 ZNode 會被自動刪除,此時認爲鎖已經釋放。

當鎖被釋放後,其他服務節點則再次去競爭性地進行創建,但每次都只有一個服務節點能夠獲取到鎖,這就是排他鎖。

5.5 集羣管理

Zookeeper 還能解決大多數分佈式系統中的問題:

  • 如可以通過創建臨時節點來建立心跳檢測機制。如果分佈式系統的某個服務節點宕機了,則其持有的會話會超時,此時該臨時節點會被刪除,相應的監聽事件就會被觸發。
  • 分佈式系統的每個服務節點還可以將自己的節點狀態寫入臨時節點,從而完成狀態報告或節點工作進度彙報。
  • 通過數據的訂閱和發佈功能,Zookeeper 還能對分佈式系統進行模塊的解耦和任務的調度。
  • 通過監聽機制,還能對分佈式系統的服務節點進行動態上下線,從而實現服務的動態擴容。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章