1. 程式人生 > >Zookeeper概述(譯)

Zookeeper概述(譯)

ZooKeeper是一個用於分散式應用的開源分散式協調服務。它提供了簡單的原語集合,分散式應用可在這些原語之上構建用於同步、配置維護、分組和命名的高層服務。ZooKeeper的設計使得程式設計容易,並且使用類似於廣泛熟知的檔案系統目錄樹結構的資料模型。它執行在Java環境中,但是有Java和C語言繫結。

分散式協調服務是出了名的難得編寫正確,很容易出現競爭條件和死鎖之類的錯誤。ZooKeeper的動機是減輕分散式應用開發協調服務的負擔。

1 設計目標

1.1 簡單

ZooKeeper讓分散式程序可通過共享的、與標準檔案系統類似的分層名字空間相互協調。名字空間由資料暫存器(在ZooKeeper世界中稱作

znode)構成,這與檔案和目錄類似。與用於儲存裝置的典型檔案系統不同的是,ZooKeeper在記憶體中儲存資料,這讓其可以達到高吞吐量和低延遲。

ZooKeeper的實現很重視高效能、高可用性,以及嚴格的順序訪問。效能意味著可將ZooKeeper用於大的分散式系統。可靠性使之可避免單點失敗。嚴格的順序訪問使得客戶端可以實現複雜的同步原語。

1.2 自我複製

與它所協調的程序一樣,ZooKeeper本身也會試圖在一組主機間進行復制這就是叢集。

組成ZooKeeper服務的各個伺服器必須相互知道對方。它們在記憶體中維護狀態和事務日誌,還在永久儲存中維護快照。只要大部分伺服器可用,ZooKeeper服務就是可用的。

客戶端連線到單個ZooKeeper伺服器。客戶端維持一個TCP連線,通過這個連線傳送請求、接收響應、獲取觀察事件,以及傳送心跳。如果到伺服器的TCP連線斷開,客戶端會連線到另一個伺服器。

1.3 順序訪問

ZooKeeper為每次更新設定一個反映所有ZooKeeper事務順序的序號。併發操作可使用序號來實現更高層抽象,如同步原語。

1.4 高速

在讀操作為主的負載下特別快。ZooKeeper應用執行在成千上萬臺機器中,在讀操作比寫操作頻繁,二者比例約為10:1的情況下效能最好。

2 資料模型和分層的名字空間

ZooKeeper提供的名字空間與標準檔案系統非常相似。名字是一個由斜槓/分隔的路徑元素序列。ZooKeeper名字空間中的每個

節點都由其路徑標識。

3 節點和臨時節點

與標準檔案系統不同,ZooKeeper名字空間中的每個節點都可以有關聯的資料以及子節點。這就像一個允許檔案也是目錄的檔案系統。(ZooKeeper設計用於儲存協調資料:狀態資訊、配置、位置資訊等,所以通常儲存在每個節點中的資料很小,在位元組到千位元組範圍內)討論ZooKeeper資料節點時,我們用術語znode來明確指示。

Znode會維護一個stat結構體,其中包含資料和ACL的版本號與時間戳,以便於進行快取驗證和協調更新。每次修改znode資料時,版本號會增長。客戶端獲取資料的時候,也同時獲取資料的版本。

對znode資料的讀寫操作是原子的。讀取操作獲取節點的所有資料,寫入操作替換所有資料。節點的訪問控制列表(ACL)控制可以進行操作的使用者。

ZooKeeper具有臨時節點的概念。只要建立節點的會話是活動的,臨時節點就存在。一旦會話終止,臨時節點會被刪除。臨時節點對於實現tbd是很有用的。

4 條件更新和觀察

ZooKeeper支援觀察的概念。客戶端可以在znode上設定觀察。觀察將在znode修改時被觸發和移除。觀察被觸發時客戶端會收到一個數據包,指示znode已經被修改。如果與ZooKeeper服務之間的連線斷開,客戶端會收到一個本地通知。這可用於tbd。

5 保證

ZooKeeper非常高效和簡單。基於其目標:成為構建如同步這樣的更復雜服務的基礎,ZooKeeper提供下述保證:

順序一致性:客戶端的更新將以請求傳送的次序被應用。

原子性:更新要麼成功,要麼失敗,沒有部分更新。

單一系統映象:無論連線到哪個伺服器,客戶端將看到一樣的檢視。

可靠性:更新操作的結果將是持續的,直到客戶端覆蓋了更新。

及時性:在某個時間範圍內,客戶端檢視確保是最新的。

關於這些保證的詳細資訊,以及如何使用這些保證,請參看tbd。

6 簡單的API

ZooKeeper的設計目標之一是提供非常簡單的程式設計介面。ZooKeeper僅支援這些操作:

create:在樹中某位置建立一個節點。

delete:刪除一個節點。

exists:測試某位置是否存在某節點。

get data:讀取節點資料。

set data:向節點寫入資料。

get children:獲取子節點列表。

sync:等待資料傳播。

關於這些操作的更深入討論,以及如何使用它們來實現更高層的操作,請參看tbd。

7 實現

下圖顯示了ZooKeeper服務的高層元件。除了請求處理器(Request Processor)之外,組成ZooKeeper服務的每個伺服器擁有每個元件的自有拷貝。

自我複製資料庫(replicated database)是一個包含整個資料樹的記憶體資料庫。更新會記錄到磁碟中以便可以恢復,並且將寫操作應用到記憶體資料庫之前會先寫入到磁碟。

每個ZooKeeper伺服器都為客戶服務。客戶端連線到一個伺服器,提交請求。讀請求由每個伺服器資料庫的本地拷貝進行服務。改變服務狀態的請求和寫請求由一致性協議處理。

作為一致性協議的一部分,客戶端的所有寫請求都被轉發到單個伺服器,也就是領導者。其他ZooKeeper伺服器則是跟隨者,它們接收來自領導者的建議,對傳遞的訊息達成一致。訊息層考慮了替換失敗的領導者和跟隨者與領導者同步的問題。

ZooKeeper使用定製的原子訊息協議。因為訊息層是原子的,ZooKeeper可保證本地拷貝不會發散(diverge)。收到寫請求時,領導者計算寫入操作後系統的狀態,將其轉換成一個捕獲此狀態的事務。

8 使用

ZooKeeper的程式設計介面非常簡單。但是,可將其用於實現高層順序操作,如同步原語、組成員管理、所有者關係管理等。更多資訊請參看tbd。

9 效能

ZooKeeper被設計為高效能的。但它真的是高效能的嗎?Yahoo研究中心的ZooKeeper開發團隊證實了ZooKeeper的高效能,特別是在讀操作比寫操作多的應用中(見下圖),因為寫操作涉及在所有伺服器間同步狀態。(讀操作寫操作是協調服務的典型情況)

上圖是ZooKeeper 3.2在配置有兩個2GHz Xeon處理器和兩個SATA 15K RPM驅動器的伺服器上執行時的吞吐率圖形。一個驅動器配置為ZooKeeper日誌專用裝置。快照寫入到作業系統驅動器。讀寫操作1KB的資料。“伺服器數”指是ZooKeeper叢集的大小,即組成服務的伺服器個數。大約30個其他伺服器用於模擬客戶端。ZooKeeper叢集配置為不允許客戶端連線到領導者。

提示:3.2版的讀寫效能是3.1版的2倍。

Benchmarks也表明ZooKeeper是可靠的。(第10節的圖)顯示了ZooKeeper在各種失敗情況下的反應。圖中標記的各個事件是:

1.跟隨者失敗和恢復

2.另一個跟隨者失敗和恢復

3.領導者失敗

4.兩個跟隨者失敗和恢復

5.另一個領導者失敗

10 可靠性

為揭示在有失敗注入時系統的行為,我們一個由7臺機器組成的ZooKeeper服務執行和先前一樣的benchmark測試,但是讓寫操作的百分比固定為30%,這是預期負載比例的保守估計

此圖有幾處值得仔細觀察。首先,如果跟隨者失敗後快速恢復,則ZooKeeper可以維持高吞吐率。但更重要的是,領導者選舉演算法讓系統可以足夠快地恢復,以阻止吞吐率有實質性的下降。據我們觀察,ZooKeeper選舉一個新的領導者的時間小於200ms。第三,一旦跟隨者恢復並且開始處理請求,ZooKeeper可以恢復高吞吐率。

11 ZooKeeper工程

ZooKeeper已經在很多工業應用中成功使用。Yahoo!在Yahoo! Message Broker中使用ZooKeeper作為協調和故障恢復服務。Yahoo! Message Broker是一個高度擴充套件的釋出-訂閱系統,管理著成千上萬個需要拷貝和資料傳遞的話題。Yahoo!的很多廣告系統也使用ZooKeeper來實現可靠服務。

我們鼓勵使用者和開發者加入社群,貢獻技能。更多資訊請看