ZooKeeper:分布式應用程式的分布式協調服務

ZooKeeper 是一個分佈式應用程序的分佈式的,開源的協調服務。它提供了一組簡單的原語,分佈式應用程序可以基於它為同步,配置維護,分組和命名而實現更高層的服務。它被設計為易於編程的,它使用了我們熟悉的文件系統目錄樹結構風格的數據模型。它運行於 Java 中,但具有 Java 和 C 的綁定。

眾所周知,協調服務很難實現。它們特別容易出現諸如競態條件和死鎖這樣的錯誤。ZooKeeper 背後的動機是解除分佈式應用程序從頭開始實現協調服務的責任。

設計目標

ZooKeeper 是簡單的。ZooKeeper 允許分佈式進程通過一個共享的與標準文件系統的組織方式類似的分層命名空間相互協作。命名空間由數據寄存器組成 - 在ZooKeeper的說法中稱為 znodes - 且它們與文件和目錄類似。不像為存儲而設計的典型文件系統那樣,ZooKeeper 在內存中保存數據,這意味著 ZooKeeper 可以實現高吞吐量和低延遲數量。

ZooKeeper 實現非常重視高性能,高可用性,嚴格有序的訪問。ZooKeeper 的性能方面意味著它可以在大型分佈式系統中使用。可靠性方面使其不會出現單點失敗的問題。嚴格有序意味著可以在客戶端實現複雜的同步原語。

ZooKeeper 是冗餘的。如同它協調的分佈式進程那樣,ZooKeeper 本身旨在通過稱為 ensemble 的一組主機間進行復制。

ZooKeeper:分佈式應用程序的分佈式協調服務

組成 ZooKeeper 服務的服務器必須彼此瞭解。它們維護內存中的狀態鏡像,以及持久性存儲中的事務日誌和快照。只要大部分服務器可用,ZooKeeper 服務就可用。

客戶端連接到一個 ZooKeeper 服務器。客戶端維護一個 TCP 連接,通過它發送請求,獲得響應,獲得觀察事件,併發送心跳。如果與服務器的 TCP 連接斷開了,客戶端將連接一個不同的服務器。

ZooKeeper 是有序的。ZooKeeper 以一個可以反映在所有 ZooKeeper 事務中的順序的數字標記每次更新。後續的操作可以使用順序實現更高層的抽象,比如同步源語。

ZooKeeper 是快速的。在 “讀取為主導” 工作負載中特別快。ZooKeeper 應用程序運行於幾千臺機器上,在讀取比寫入更常見,比例大約為 10:1 的情況下它執行地最好。

數據模型和分層命名空間

ZooKeeper 提供的命名空間與標準的文件系統非常像。名字是由反斜線(/)分割的一系列路徑元素。ZooKeeper 命名空間中的每個節點由一個路徑標識。

ZooKeeper:分佈式應用程序的分佈式協調服務

節點和短暫節點

不像標準的文件系統,ZooKeeper 命名空間中的每個節點都可以有與其關聯的數據和子節點。它就像一個允許文件同時是目錄的文件系統。(ZooKeeper 被設計為用於存儲協調數據:狀態信息,配置,位置信息,等等,因此每個節點所存儲的數據通常都很小,在字節到千字節範圍內。)我們使用術語 znode 使我們討論的 ZooKeeper 數據節點更清晰。

Znodes 維護一個狀態結構,其中包含數據修改的版本號,ACL 修改,和時間戳,以允許緩存驗證和協調更新。每次 znode 的數據修改了,其版本號都增加。例如,每當客戶端檢索數據時,它也接收數據的版本號。

命名空間中的每個 znode 所存儲的數據的讀和寫都是原子的。讀取獲得與一個 znode 關聯的所有數據字節,寫入替換所有的數據。每個節點具有一個訪問控制表(ACL),其限制了誰可以做什麼。

ZooKeeper 還有臨時節點的概念。這些 znodes 的生命期與創建 znode 的會話活躍期一樣長。當會話結束時則 znode 被刪除。當你想要實現 [tbd] 時臨時節點很有用。

條件更新和觀察點

ZooKeeper 支持 觀察點 的概念。客戶端可以在 znodes 上設置觀察點。當 znode 修改時觀察點將被觸發並被移除。觀察點被觸發時,客戶端收到一個包,說明 znode 被修改了。如果客戶端和其中一個 ZooKeeper 服務器之間的連接斷開了,客戶端將收到一個本地通知。這些可以被用於 [tbd] 。

保證

ZooKeeper 非常快速且非常簡單。由於它的目標是成為構建更復雜的服務的基礎設施,比如同步,它提供了一系列保證。包括:

  • 順序一致性 - 來自於客戶端的更新將以它們被髮送的順序應用。
  • 原子性 - 更新要麼成功要麼失敗。沒有部分結果。
  • 單系統鏡像 - 客戶端將看到服務相同的視圖,無論它連接的是哪個服務器。
  • 可靠性 - 一旦應用了一個更新,則它將從那一刻持久化,直到客戶端覆寫了更新。
  • 及時性 - 系統的客戶端視圖被保證在一定的時間範圍內保持最新。

欲瞭解更多關於此的信息,及它們如何使用,請參考 [tbd] 。

簡單的 API

ZooKeeper 的一個設計目標是提供非常簡單的編程接口。因此,它僅支持以下操作:

create - 在樹的特定位置創建一個節點

delete - 刪除節點

exists - 測試特定位置節點是否存在

get data - 從節點讀取數據

set data - 向節點寫入數據

get children - 提取節點的子節點列表

sync - 等待數據傳播

要獲得關於這些內容更深入的討論,及如何使用它們實現更高層的操作,請參考 [tbd] 。

實現

ZooKeeper Components 展示了 ZooKeeper 服務的高層組件。除了請求處理器之外,組成 ZooKeeper 服務的每個服務器都複製其自己的每個組件的副本。

ZooKeeper:分佈式應用程序的分佈式協調服務

複製的數據庫是一個內存數據庫,其包含了完整的數據樹。為了可恢復性,更新被志記在磁盤中,在寫操作被應用於內存數據庫之前它們先被序列化進磁盤中。

每個 ZooKeeper 都為客戶端提供服務。客戶端連接到一個特定的服務器來提交請求。讀取請求由每個服務器數據庫的本地複製提供服務。改變服務的狀態的請求,寫請求,由一個一致性協議處理。

作為一致性協議的一部分,所有來自於客戶端的寫請求被轉發給一個特定的服務器,稱為 leader 。其它的 ZooKeeper 服務器,稱為 followers ,接收來自 leader 的消息提議並同意消息傳遞。消息傳遞層負責替換失敗的 leaders 並將 followers 與 leaders 同步。

ZooKeeper 使用一個定製的原子性消息協議。由於消息傳遞層是原子的,ZooKeeper 可以保證本地副本永遠不會分叉。當 leader 接收到一個寫請求時,它計算寫操作應用時系統的狀態,並把這轉換為捕獲新狀態的事務。

使用

ZooKeeper 的編程接口很簡單。然而通過它你可以實現更高級的順序操作,比如同步原語,組成員身份,所有權等。一些分佈式應用程序已經使用它: [tbd: add uses from white paper and video presentation.] 更多信息,請參考 [tbd] 。

性能

ZooKeeper 的設計目標是高性能。但是做到了麼?Yahoo! Research 的 ZooKeeper 開發團隊的結果表明做到了。(參考 ZooKeeper 吞吐量隨讀-寫比例變化的變化 。)在讀取數量超過寫入的應用程序中,它的性能特別高,因為寫操作包括同步所有服務器的狀態。(讀取數量超過寫入是典型的協調服務的場景。)

ZooKeeper:分佈式應用程序的分佈式協調服務

ZooKeeper 吞吐量隨讀-寫比例變化的變化 是 ZooKeeper 發行版 3.2 運行於雙 2Ghz Xeon 和 SATA 15K RPM 驅動器的服務器上的吞吐量圖。一個驅動器被用作專門的 ZooKeeper 志記設備。快照被寫入 OS 驅動器。寫請求是 1K 的寫操作,讀請求是 1K 的讀操作。圖中的 “Servers” 是 ZooKeeper 集群的大小,組成服務的服務器的數量。接近 30 臺其它服務器被用於模擬客戶端。ZooKeeper 集群被配置為 leaders 不允許接受來自於客戶端的連接。

基準測試也展示了它是可靠的。

錯誤出現時的可靠性 展示了部署如何響應各種失敗。圖中標記的事件如下:

  1. 一個 follower 的失敗和恢復
  2. 一個不同的 follower 的失敗和恢復
  3. Leader 的失敗
  4. 兩個 follower 的失敗和恢復
  5. 另一個 leader 的失敗

可靠性

為了展示系統隨著時間和失敗的插入的行為,我們運行了一個由 7 臺服務器組成的 ZooKeeper 服務。我們之前運行了相同的飽和基準測試,但是這次我們將寫的百分比固定在 30%,這是我們預期工作負載的保守比率。

ZooKeeper:分佈式應用程序的分佈式協調服務

這張圖中有一些重要的觀察。首先,如果 followers 失敗並快速恢復,則儘管有失敗, ZooKeeper 依然能夠承受很高的吞吐量。但可能更重要地是,leader 選舉算法允許系統足夠快地恢復過來,以防止吞吐量大幅下降。在我們的觀察中,ZooKeeper 選舉新 leader 耗費的時間小於 200ms。第三,至於 followers 恢復,一旦它們開始處理請求,ZooKeeper 可以再次提升吞吐量。

ZooKeeper 項目

ZooKeeper 已經成功地被用於許多工業級的應用程序中了。在 Yahoo!,它被用作

Yahoo! Message Broker 的協調和失敗恢復服務,Yahoo! Message Broker 是一個高可擴展的發佈-訂閱系統,其為複製和數據傳遞管理著幾千個 topics。Yahoo! crawler 的 Fetching Service 也使用了它,其中 ZooKeeper 也管理失敗恢復。大量的 Yahoo! 廣告系統服務也使用 ZooKeeper 來實現可靠的服務。

對Java微服務、分佈式、高併發、高可用、大型互聯網架構技術、面試經驗交流感興趣的。可以關注我的頭條號,我會在微頭條不定期的發放免費的資料鏈接,這些資料都是從各個技術網站蒐集、整理出來的,如果你有好的學習資料可以私聊發我,我會註明出處之後分享給大家。歡迎分享,歡迎評論,歡迎轉發!


分享到:


相關文章: