分布式系統的好兄弟-ZooKeeper

信息飛速膨脹,很多應用無法依賴單個服務器處理龐大的數據量。由於分佈式系統和應用可以提供更強的計算能力,還能更好地容災和擴展,所以逐漸受到青睞。

在開發分佈式應用時,通常需要花費大量時間和精力來處理異構系統中的協作通信問題。

什麼是 ZooKeeper

ZooKeeper 專注於任務協作,能為大型分佈式系統提供可靠的協作處理能力,簡化開發流程,讓開發人員更專注於應用本身的邏輯。

ZooKeeper 具有 C-S 結構,在使用時,開發的應用可以看做為連接到 ZooKeeper 服務器的客戶端,通過客戶端 API 進行操作,保障強一致性、有序性和持久性,具有實現同步原語的能力,提供簡單的併發處理機制。常見的用法如:選舉主節點、崩潰檢測、存儲元數據等。

注意,ZooKeeper 不適用於海量信息存儲,設計應用時最好將應用數據與協同數據分開,使用數據庫、分佈式文件系統等存儲應用數據。

ZooKeeper 基礎

由若干條指令組成,用於完成特定功能的過程稱為原語。

為了保證靈活性,ZooKeeper 不直接提供原語,而是暴露出類似文件系統的 API,讓開發人員通過 API 實現自己的原語,通常使用菜譜( recipes )來表示原語的實現。

ZooKeeper 操作和維護的為一個個數據節點,稱為 znode,採用類似文件系統的層級樹狀結構進行管理。如果 znode 節點包含數據則存儲為字節數組(byte array)。

API 概述

ZooKeeper 暴露如下 API:

  • create /path data 創建節點幷包含數據
  • delete /path 刪除節點
  • exists /path 檢查節點是否存在
  • setData /path data 設置節點數據
  • getData /path 獲取節點數據
  • getChildren /path 獲取子節點列表

ZooKeeper 不允許局部讀取或寫入數據,讀取時會將節點數據全部讀取,寫入時會整個替換。

節點類型

創建 znode 時需要指定節點類型,節點的類型會影響其行為方式。

znode 分為持久節點和臨時節點。持久節點只有通過調用 delete API 才能刪除;臨時節點在客戶端崩潰或關閉與 ZooKeeper 服務器連接時就會被刪除,調用 delete API 也能刪除臨時節點。

znode 可設置為有序節點。有序節點在創建時會分配一個整數序號追加到路徑之後,如創建 /tasks/task- 有序節點,追加整數後節點路徑為 /tasks/task-1 。

綜上,znode 共有 4 種類型,分別為:持久(無序)、臨時(無序)、持久有序和臨時有序。

監聽通知

ZooKeeper 通常以遠程服務的方式被訪問,在數據不發生變化時頻繁地訪問代價較大,ZooKeeper 的通知機制可以代替客戶端的輪訓。

客戶端通過設置監視點(watcher)向 ZooKeeper 註冊需要接收通知的 znode,在 znode 發生變化時 ZooKeeper 向客戶端發送消息。

通知機制是單次觸發的操作,如需不斷監聽 znode 的變化,需要在接收到 znode 變更時設置新的監視點。

監視點有多種類型,如監控 znode 數據變化、監控 znode 子節點變化、監控 znode 創建或刪除。

版本匹配

每個 znode 都有一個隨數據變化而自增的版本號,多個寫入操作會有條件的執行。寫入操作會將版本號作為參數,當與服務器上版本號一致時才會調用成功,這點在多個客戶端對同一個 znode 進行操作時很重要。

仲裁模式

只有一臺單獨的 ZooKeeper 服務器時為獨立模式,狀態無法複製。具有一組 ZooKeeper 服務器時為仲裁模式,仲裁模式下各個服務器間進行狀態的複製,同時服務於客戶端的請求。

仲裁模式下,如果讓客戶端等待所有服務器完成數據保存再繼續,延遲問題就會很大,ZooKeeper 通過法定人數確定工作時必須有效運行的服務器最小數量。如果有 5 臺服務器,任意 3 臺服務器保存了數據,客戶端就可以繼續工作。其他 2 臺服務器最終也會捕獲到數據進行保存。

服務器的個數應該為奇數,如有 5 臺服務器,則最多允許 2 臺崩潰。假如服務器個數為偶數,允許崩潰的服務器數量不會增加,法定人數卻更大,需要更多的確認操作。

開始使用 ZooKeeper

開始使用 ZooKeeper 之前,需要 下載 ZooKeeper 發行包 。解壓 tar 格式的壓縮文件,bin 目錄下有啟動 ZooKeeper 的腳本,conf 目錄下存放著 ZooKeeper 的配置文件,lib 目錄下存放著一些運行所需的第三方文件。

啟動服務器

在 ZooKeeper 目錄下執行以下命令啟動 ZooKeeper 服務器。

$ bin/zkServer.sh start

啟動客戶端

$ bin/zkCli.sh

列出根節點下的所有節點

[zk: localhost:2181(CONNECTED) 0] ls /

[zookeeper]

創建節點

[zk: localhost:2181(CONNECTED) 1] create /test ""

Created /test

[zk: localhost:2181(CONNECTED) 2] ls /

[zookeeper, test]

刪除節點

[zk: localhost:2181(CONNECTED) 3] delete /test

[zk: localhost:2181(CONNECTED) 4] ls /

[zookeeper]

退出客戶端

[zk: localhost:2181(CONNECTED) 5] quit

Quitting...

2018-05-02 15:58:34,004 [myid:] - INFO [main:ZooKeeper@684] - Session: 0x1630a0cdc400001 closed

2018-05-02 15:58:34,006 [myid:] - INFO [main-EventThread:ClientCnxn$EventThread@519] - EventThread shut down for session: 0x1630a0cdc400001

關閉服務器

$ bin/zkServer.sh stop


分享到:


相關文章: