zookeeper 學習筆記

預流發表於2018-01-24

基本概念

  1. 角色 zookeeper 叢集中的節點共有三種角色,每個節點同時只能是一種角色。叢集中的所有機器通過一個 Leader 選舉過程來選定一臺被稱為 Leader 的機器。 Leader:接受所有 Follower 的提案請求並統一協調發起提案的投票,負責與所有的 Follower 進行內部的資料交換 Follower:直接為客戶端服務並參與提案的投票,同時與 Leader 進行資料交換 Observer:直接為客戶端服務但不參與提案的投票,同時也與 Leader 進行資料交換

  2. 會話 zookeeper 中客戶端啟動時會與伺服器建立一個 TCP 連線,從第一次連線建立開始,客戶端會話的生命週期就開始了,通過這個連線,客戶端能夠通過心跳檢測與伺服器保持有效的會話,也能夠向伺服器傳送請求並接受響應,還能夠接收來自伺服器的 watch 事件通知。

  3. 節點 一般在分散式語境下的節點是指組成叢集的每一臺伺服器,在 zookeeper 中還有另外一層意思,稱之為資料節點(ZNode)。  zookeeper 的整個名字空間的結構是層次化的,和 Linux 檔案系統結構相似,是一顆樹。名字空間的層次由斜槓(/)來進行分割,在名稱空間裡面的每一個節點的名字空間由這個結點的路徑來確定。 每個 ZNode 上都會儲存自己的資料內容,同時還會儲存一系列屬性資訊。

  4. 版本 對於每個 ZNode ,zookeeper 都會為它維護一個叫 Stat 的資料結構,Stat 中記錄了 ZNode 的三個資料版本,version(當前ZNode資料內容的版本號)、cversion(當前ZNode子節點的版本號)、aversion(當前ZNode的ACL變更版本號)

  5. watcher zookeeper 允許使用者在指定節點上註冊一些 watcher,並且在特定事件觸發的時候,zookeeper 服務端會將事件通知到感興趣的客戶端,該機制是 zookeeper 實現分散式協調服務的重要特性。

客戶端命令

這裡列出常用的客戶端命令,所謂客戶端命令指使用 zkCli 連線到 zookeeper 伺服器之後使用的命令,zkCli 連線的語法如下: zkCli -server host:port cmd args zkCli 是客戶端可執行檔名,根據具體作業系統環境可能是 zkCli.sh 或 zkCli.cmd host 是伺服器IP或域名,port 是伺服器埠號,如果有多個伺服器地址則用逗號分隔 cmd 是具體命令、args 是命令的引數,也可以連線上伺服器之後再執行命令。

  1. 檢視節點 ls /path 檢視名為 /path 的子節點,但只能檢視指定節點下的第一級的所有子節點。 ls2 /path 檢視名為 /path 的子節點,並且能看到更新次數等屬性資訊。

  2. 建立節點 create [-s] [-e] /path data 建立一個名叫 /path 的節點,幷包含資料 data。加上 -s 表示建立的是順序節點,加上 -e 表示建立的是臨時節點,如果都不加則預設為建立持久節點。

  3. 刪除節點 delete /path 刪除名為 /path 的節點

  4. 設定節點資料 set /path data 設定名為 /path 的節點的資料為 data

  5. 返回節點資料 get /path 返回名為 /path 的節點的資料和屬性資訊

  6. 強制同步資料 sync /path 將名為 /path 的節點強制同步為最新的資料

  7. 幫助資訊 help 幫助命令,顯示客戶端支援的命令及語法格式

  8. 退出 quit 退出當前客戶端,會話結束。

運維命令

zookeeper 提供了一些四字命令用於獲取 zookeeper 服務端的當前狀態及相關資訊,這些命令在系統運維時很有用。使用者在客戶端可以通過 telnet 或 nc 向zookeeper 提交相應的命令,比如 nc 方式: echo cmd|nc host port cmd 是具體的命令(因為一般是四個字母所以又叫做四字命令),host 是zookeeper 伺服器 IP 地址或域名,port 是 zookeeper 埠號

  1. conf 顯示服務配置的詳細資訊,比如資料檔案目錄、日誌檔案目錄、間隔單位時間、選舉演算法、選舉埠等。

  2. cons 列出所有連線到伺服器的客戶端的完全的連線/會話的詳細資訊。包括”接受 / 傳送”的包數量、會話 id 、操作延遲、最後的操作執行等。

  3. crst 重置所有連線。

  4. dump 列出未經處理的會話和臨時節點。

  5. envi 顯示關於伺服器環境的詳細資訊,比如 zookeeper 版本、作業系統版本、jdk 地址等。

  6. reqs 列出未經處理的請求。

  7. ruok 測試服務是否處於正確狀態。如果確實如此,那麼服務返回“imok ”,否則不做任何相應。

  8. stat 輸出關於效能和連線的客戶端的列表。

  9. wchs 列出伺服器 watch 的詳細資訊。

  10. wchc 通過 session 列出伺服器 watch 的詳細資訊,它的輸出是一個與 watch 相關的會話的列表。

  11. wchp 通過路徑列出伺服器 watch 的詳細資訊,它的輸出是一個與 session 相關的路徑。

上面列出的是一些常用的四字命令,更詳細資訊可以參考zookeeper的官方文件,裡面的【ZooKeeper Commands】一節有具體介紹。

特性

  1. 一致性 zookeeper 很好地保證在分散式高併發情況下節點的建立一定是全域性唯一性,即保證客戶端無法重複建立一個已經存在的資料節點。 根據 CAP 理論,分散式系統只能滿足一致性(Consistence)、可用性(Availability)、分割槽容錯性(partitioning)三項中的兩項而不可能滿足全部三項。對於 zookeeper 來說,其實現了 A 可用性、P 分割槽容錯性、C 中的寫入強一致性,喪失的是 C 中的讀取一致性。 更進一步解釋,zookeeper 的一致性保證包括以下幾點:
  • 順序一致性 一個客戶端的更新將按照傳送的順序被寫入到服務端。
  • 原子性 更新要麼成功,要麼失敗,沒有部分結果。
  • 單一系統映象 客戶端只會連線 host 列表中狀態最新的那些例項。如果正在連線到的例項掛了,客戶端會嘗試重新連線到叢集中的其他例項,那麼此時滯後於故障例項的其它例項都不會接收該連線請求,只有和故障例項版本相同或更新的例項才接收該連線請求。
  • 永續性 寫操作完成之後將會被持久化儲存,不受伺服器故障影響。
  • 併發一致性 zookeeper 並不保證在某個時刻兩個不同客戶端具有一致的資料檢視,因為網路的延遲一個客戶端可能在另一個客戶端得到修改通知之前進行更新。如果不同客戶端讀取到相同的值很重要,那麼客戶端應該在執行讀取操作之前呼叫 sync() 方法,使得讀操作的連線所連的 zookeeper 例項能與 leader 進行同步,從而能讀到最新的類容。
  1. watcher 監聽 客戶端如果對一個節點註冊 watcher 監聽,那麼當該節點的內容或其子節點發生變更時,zookeeper 伺服器會向訂閱的客戶端傳送變更通知。

  2. 臨時節點 對在 zookeeper 上建立的臨時節點,一旦客戶端與伺服器之間的會話失效,那麼該臨時節點就被自動清除。

  3. 順序節點 客戶端申請建立該節點時 zookeeper 會自動在節點路徑末尾新增遞增序號

應用場景

  1. 資料訂閱釋出 將應用中的配置資訊放在 zookeeper 中集中管理。應用在啟動時主動到zk服務端進行一次配置資訊的獲取,同時在指定節點註冊一個 watcher 監聽。這樣只要配置資訊發生變更,服務端都會實時通知到所有訂閱的客戶端。

  2. 域名服務 將域名配置資訊放在 zookeeper 上,對外提供一套域名註冊、域名解析、域名可用性檢測的服務。基於此提供一套動態的 DNS 服務。

  3. 全域性唯一 ID 可以利用順序節點的特性生成全域性唯一的 ID。

  4. 分散式協調通知 利用 watcher 監聽實現系統間的協調和通知,從而實現資料變更的處理。不同客戶端都對 zookeeper 上同一個資料節點進行 watcher 註冊,如果資料節點發生變化,那麼所有訂閱的客戶端都能受到通知。

  5. Master 選舉 利用 zookeeper 建立節點時的強一致性,由客戶端叢集定時往 zookeeper 上建立同一個名字的臨時節點。在這個過程中只有一個客戶端能夠建立成功,那麼該客戶端就成了 Master,同時其他沒有建立成功的客戶端都在該節點註冊一個節點變更的 watcher,用於監控當前 Master 機器是否存活,一旦發現 Master 掛掉其餘客戶端重新進行 Master 選舉。

  6. 分散式鎖

  • 排他鎖 利用強一致性,將 zookeeper 上的一個臨時節點表示為一個排他鎖,所有客戶端同時建立該節點,最終只有一個客戶端能建立成功,那麼就認為該客戶端獲得了鎖,同時註冊該節點的 watcher 監聽。當移除該節點就認為釋放了鎖。

  • 共享鎖 利用強一致性,將 zookeeper 上的一個臨時順序節點表示為一個共享鎖,並註冊同級子節點的 watcher 監聽。判斷讀寫順序時根據不同需求關注比自己序號小的同級子節點型別。

相關文章