從零到一 之 ZooKeeper(一)
所有內容翻譯自官網
簡介
ZooKeeper 提供了一種分布式應用程序的高性能協同服務。它封裝了一些基礎公共服務,例如:命名,配置管理,同步和組服務,並提供簡單易用的開發接口。我們可以利用 ZooKeeper 來直接實現一致性,組管理,領導選舉和存在協議等功能。當然,我們也可以利用它實現我們特殊的需求。
概覽
ZooKeeper 是一種分布式、開源的協同服務。它暴露了一組簡單的原語,分布式應用程序可以基於該原語組,實現更高級的服務,如同步、配置維護、組別和命名。它是一種編程友好型的設計,並采用大家熟悉的文件係統的目錄樹結構作為數據模型,可以用 Java 運行,也可以和 C 綁定。
協同服務很難正確運行,經常出現競爭危害和死鎖。ZooKeeper 的目的就是降低協同服務實現與維護的成本。
設計目標
易用性,ZooKeeper 允許分布式進程通過與標準文件係統類似的**共享層次命名空間**互相協同。命名空間由數據節點(znodes)組成,類似於文件與目錄。與專為存儲設計的典型文件係統不同,ZooKeeper的數據都保存在內存中,以獲得高吞吐和低時延的特性。
ZooKeeper實現了高性能、高可用和嚴格有序。高性能意味著可以被應用在大型分布式係統,高可用則避免了單點故障的風險,嚴格有序保證了複雜的同步原語可以在客戶端實現。
可複製,就像它所協同的分布式進程一樣,ZooKeeper 的組件也是可複製的
構成 ZooKeeper 服務的服務器必須互相感知,它們各自維護了一張相同的內存狀態鏡像,以及持久存儲的事務日誌與快照,隻要大部分的服務器可用,ZooKeeper 的服務就可以正常運行。
客戶端會維護與某一台 ZooKeeper 服務器的 TCP 長連接,並通過該連接進行請求發送,響應接收,監聽事件獲取與心跳檢測。如果當前 TCP 長連接斷開,客戶端會向另一台服務器發起連接請求。
有序性,ZooKeeper 為每一次更新標記了一個序號,以反映所有事務的順序。後續操作可以使用該序號實現更高級的抽象,例如同步原語。
速度快,ZooKeeper 在“讀頻繁”工作流中表現非常快,在數千台集群中運行,讀寫比為 10:1 時,性能最好。
數據模型與層次命名空間
ZooKeeper 提供的命名空間類似於標準文件係統,名稱是以斜杠(/)分隔的路徑元素序列。ZooKeeper 命名空間中的每個節點都有唯一的路徑標識。
不同於標準文件係統,ZooKeeper 命名空間中的每個節點都可以持有數據與子節點(文件亦是目錄)。ZooKeeper 被設計用於存儲協同數據,如狀態信息,配置,位置信息等,因此存儲在每個節點上的數據量都比較小,一般不到1KB。接下來,我們采用術語 znode 表明我們正在談論 ZooKeeper 中的數據節點。
znode 維護一了個統計結構,其中包含數據變更,ACL變更與時間戳的版本號,以允許緩存驗證和協調更新。每次 znode 的數據發生變化時,它的版本號都會增加。例如,每當客戶端檢索數據時,它也會收到該數據的版本信息。
命名空間中每個 znode 存儲的數據,都以原子方式進行讀取與寫入。讀取將獲得該 znode 關聯的所有數據字節,寫入則替換所有數據。每個節點都有一個訪問控製列表(ACL),它限製誰可以做什麼。
ZooKeeper 還提供了一種臨時節點,它們的生命周期取決於創建它們的會話(session),當會話結束時,臨時節點將會被刪除。
條件更新與監聽
ZooKeeper 支持監聽功能。客戶端可以在 znode 上設置一個監聽器,當 znode 發生變更時,監聽器將被觸發並移除,與此同時,客戶端將收到一個表示 znode 變更的數據包。此外,如果客戶端與 ZooKeeper 服務器的 TCP 連接斷開時,客戶端將收到一個本地通知。
保證
ZooKeeper 既簡單又快速,由於其目標是提供基礎原語,以構建更為複雜的服務,因此,它提供了一係列的保證。
- 順序一致性,客戶端的更新將按照他們發送的順序執行;
- 原子性,更新成功或失敗,沒有中間狀態;
- 單一係統映像,無論客戶端連接的是哪一台服務器,它們看到的服務視圖都是相同的;
- 可靠性,一旦更新成功,它將一直持續到被下一個客戶端更新覆蓋;
- 及時性,客戶端看到的係統視圖,在一定時間範圍內保證是最新的。
簡單 API
ZooKeeper 的設計目標之一是提供非常簡單的可編程接口,因此,它隻提供如下操作:
- 創建(creat),在目錄樹中某個位置創建一個節點;
- 刪除(delete),刪除一個節點;
- 存在性檢查(exists),測試節點是否存在於某個位置;
- 獲取數據(get data),從節點中讀取數據;
- 設置數據(set data),向節點中寫入數據;
- 獲取子節點(get children),檢索節點的子節點列表;
- 同步(syc),等待數據傳播。
實現
下圖展示了 ZooKeeper 服務的高級組件。除了請求處理器之外,組成 ZooKeeper 服務的每個服務器都會對自身的組件進行複製備份。
複製數據庫是包含完整數據樹的內存數據庫,它將更新記錄到磁盤以獲取可恢複性,並將寫入數據也序列化到磁盤上,然後再更新內存數據庫。
每個 ZooKeeper 服務器都為客戶端提供服務。客戶端需要連接到一個服務器上,才能提交請求。客戶端的讀請求,實際上是請求存儲在本地的服務端數據庫的備份。服務狀態更改請求與寫入請求則是通過一種一致性協議處理。
一致性協議規定了所有客戶端寫請求都將被轉發至單個服務器,即領導節點(Leader)。其他的 ZooKeeper 服務器被稱為 追隨者(Followers),它們接收來自 Leader 的消息提議,然後對消息的傳遞進行表決。消息傳遞層負責將 Followers 同步給 Leader,並在 Leader 發生故障時暫代履責。
ZooKeeper 使用自定義的原子消息協議,由於消息層是原子的,因此可以保證 ZooKeeper 的本地副本不會發散(保持統一),當 Leader 收到寫請求時,它會計算寫請求執行時的係統狀態是什麼,並將其轉換成捕獲該新狀態的事務操作。
最後更新:2017-08-24 12:03:56