一文了解Zookeeper

前言

相信大家對 ZooKeeper 應該不算陌生。但是你真的瞭解 ZooKeeper 是個什麼東西嗎?如果別人/面試官讓你給他講講 ZooKeeper 是個什麼東西,你能回答到什麼地步呢?

我本人曾經使用過 ZooKeeper 作爲 Dubbo 的註冊中心,另外在搭建 solr 集羣的時候,我使用到了 ZooKeeper 作爲 solr 集羣的管理工具。前幾天,總結項目經驗的時候,我突然問自己 ZooKeeper 到底是個什麼東西?想了半天,腦海中只是簡單的能浮現出幾句話:“①Zookeeper 可以被用作註冊中心。 ②Zookeeper 是 Hadoop 生態系統的一員;③構建 Zookeeper 集羣的時候,使用的服務器最好是奇數臺。” 可見,我對於 Zookeeper 的理解僅僅是停留在了表面。

所以,通過本文,希望帶大家稍微詳細的瞭解一下 ZooKeeper 。如果沒有學過 ZooKeeper ,那麼本文將會是你進入 ZooKeeper 大門的墊腳磚。如果你已經接觸過 ZooKeeper ,那麼本文將帶你回顧一下 ZooKeeper 的一些基礎概念。

最後,本文只涉及 ZooKeeper 的一些概念,並不涉及 ZooKeeper 的使用以及 ZooKeeper 集羣的搭建。 網上有介紹 ZooKeeper 的使用以及搭建 ZooKeeper 集羣的文章,大家有需要可以自行查閱。

一 什麼是 ZooKeeper

1.1 ZooKeeper 概覽

ZooKeeper 是一個開源的分佈式協調服務,ZooKeeper框架最初是在“Yahoo!"上構建的,用於以簡單而穩健的方式訪問他們的應用程序。 後來,Apache ZooKeeper成爲Hadoop,HBase和其他分佈式框架使用的有組織服務的標準。 例如,Apache HBase使用ZooKeeper跟蹤分佈式數據的狀態。ZooKeeper 的設計目標是將那些複雜且容易出錯的分佈式一致性服務封裝起來,構成一個高效可靠的原語集,並以一系列簡單易用的接口提供給用戶使用。

原語: 操作系統或計算機網絡用語範疇。是由若干條指令組成的,用於完成一定功能的一個過程。具有不可分割性·即原語的執行必須是連續的,在執行過程中不允許被中斷。

ZooKeeper 是一個典型的分佈式數據一致性解決方案,分佈式應用程序可以基於 ZooKeeper 實現諸如數據發佈/訂閱、負載均衡、命名服務、分佈式協調/通知、集羣管理、Master 選舉、分佈式鎖和分佈式隊列等功能。

Zookeeper 一個最常用的使用場景就是用於擔任服務生產者和服務消費者的註冊中心。 服務生產者將自己提供的服務註冊到Zookeeper中心,服務的消費者在進行服務調用的時候先到Zookeeper中查找服務,獲取到服務生產者的詳細信息之後,再去調用服務生產者的內容與數據。如下圖所示,在 Dubbo架構中 Zookeeper 就擔任了註冊中心這一角色。

二 關於 ZooKeeper 的一些重要概念

2.1 重要概念總結

  • ZooKeeper 本身就是一個分佈式程序(只要半數以上節點存活,ZooKeeper 就能正常服務)。
  • 爲了保證高可用,最好是以集羣形態來部署 ZooKeeper,這樣只要集羣中大部分機器是可用的(能夠容忍一定的機器故障),那麼 ZooKeeper 本身仍然是可用的。
  • ZooKeeper 將數據保存在內存中,這也就保證了 高吞吐量和低延遲(但是內存限制了能夠存儲的容量不太大,此限制也是保持znode中存儲的數據量較小的進一步原因)。
  • ZooKeeper 是高性能的。 在“讀”多於“寫”的應用程序中尤其地高性能,因爲“寫”會導致所有的服務器間同步狀態。(“讀”多於“寫”是協調服務的典型場景。)
  • ZooKeeper有臨時節點的概念。 當創建臨時節點的客戶端會話一直保持活動,瞬時節點就一直存在。而當會話終結時,瞬時節點被刪除。持久節點是指一旦這個ZNode被創建了,除非主動進行ZNode的移除操作,否則這個ZNode將一直保存在Zookeeper上。
  • ZooKeeper 底層其實只提供了兩個功能:①管理(存儲、讀取)用戶程序提交的數據;②爲用戶程序提交數據節點監聽服務。

下面關於會話(Session)、 Znode、版本、Watcher、ACL概念的總結都在《從Paxos到Zookeeper 》第四章第一節以及第七章第八節有提到,感興趣的可以看看!

2.2 會話(Session)

2.3 Znode

在談到分佈式的時候,我們通常說的“節點"是指組成集羣的每一臺機器。然而,在Zookeeper中,“節點"分爲兩類,第一類同樣是指構成集羣的機器,我們稱之爲機器節點;第二類則是指數據模型中的數據單元,我們稱之爲數據節點一一ZNode。

Zookeeper將所有數據存儲在內存中,數據模型是一棵樹(Znode Tree),由斜槓(/)的進行分割的路徑,就是一個Znode,例如/foo/path1。每個上都會保存自己的數據內容,同時還會保存一系列屬性信息。

**在Zookeeper中,node可以分爲持久節點和臨時節點兩類。所謂持久節點是指一旦這個ZNode被創建了,除非主動進行ZNode的移除操作,否則這個ZNode將一直保存在Zookeeper上。而臨時節點就不一樣了,它的生命週期和客戶端會話綁定,一旦客戶端會話失效,那麼這個客戶端創建的所有臨時節點都會被移除。**另外,ZooKeeper還允許用戶爲每個節點添加一個特殊的屬性:SEQUENTIAL.一旦節點被標記上這個屬性,那麼在這個節點被創建的時候,Zookeeper會自動在其節點名後面追加上一個整型數字,這個整型數字是一個由父節點維護的自增數字。

2.4 版本

在前面我們已經提到,Zookeeper 的每個 ZNode 上都會存儲數據,對應於每個ZNode,Zookeeper 都會爲其維護一個叫作 Stat 的數據結構,Stat中記錄了這個 ZNode 的三個數據版本,分別是version(當前ZNode的版本)、cversion(當前ZNode子節點的版本)和 cversion(當前ZNode的ACL版本)。

2.5 Watcher

Watcher(事件監聽器),是Zookeeper中的一個很重要的特性。Zookeeper允許用戶在指定節點上註冊一些Watcher,並且在一些特定事件觸發的時候,ZooKeeper服務端會將事件通知到感興趣的客戶端上去,該機制是Zookeeper實現分佈式協調服務的重要特性。

2.6 ACL

Zookeeper採用ACL(AccessControlLists)策略來進行權限控制,類似於 UNIX 文件系統的權限控制。Zookeeper 定義瞭如下5種權限。

其中尤其需要注意的是,CREATE和DELETE這兩種權限都是針對子節點的權限控制。

三 ZooKeeper 特點

  • 順序一致性: 從同一客戶端發起的事務請求,最終將會嚴格地按照順序被應用到 ZooKeeper 中去。
  • 原子性: 所有事務請求的處理結果在整個集羣中所有機器上的應用情況是一致的,也就是說,要麼整個集羣中所有的機器都成功應用了某一個事務,要麼都沒有應用。
  • 單一系統映像 : 無論客戶端連到哪一個 ZooKeeper 服務器上,其看到的服務端數據模型都是一致的。
  • 可靠性: 一旦一次更改請求被應用,更改的結果就會被持久化,直到被下一次更改覆蓋。

四 ZooKeeper 設計目標

4.1 簡單的數據模型

ZooKeeper 允許分佈式進程通過共享的層次結構命名空間進行相互協調,這與標準文件系統類似。 名稱空間由 ZooKeeper 中的數據寄存器組成 - 稱爲znode,這些類似於文件和目錄。 與爲存儲設計的典型文件系統不同,ZooKeeper數據保存在內存中,這意味着ZooKeeper可以實現高吞吐量和低延遲。

4.2 可構建集羣

爲了保證高可用,最好是以集羣形態來部署 ZooKeeper,這樣只要集羣中大部分機器是可用的(能夠容忍一定的機器故障),那麼zookeeper本身仍然是可用的。 客戶端在使用 ZooKeeper 時,需要知道集羣機器列表,通過與集羣中的某一臺機器建立 TCP 連接來使用服務,客戶端使用這個TCP鏈接來發送請求、獲取結果、獲取監聽事件以及發送心跳包。如果這個連接異常斷開了,客戶端可以連接到另外的機器上。

ZooKeeper 官方提供的架構圖:

上圖中每一個Server代表一個安裝Zookeeper服務的服務器。組成 ZooKeeper 服務的服務器都會在內存中維護當前的服務器狀態,並且每臺服務器之間都互相保持着通信。集羣間通過 Zab 協議(Zookeeper Atomic Broadcast)來保持數據的一致性。

4.3 順序訪問

對於來自客戶端的每個更新請求,ZooKeeper 都會分配一個全局唯一的遞增編號,這個編號反應了所有事務操作的先後順序,應用程序可以使用 ZooKeeper 這個特性來實現更高層次的同步原語。 這個編號也叫做時間戳——zxid(Zookeeper Transaction Id)

4.4 高性能

ZooKeeper 是高性能的。 在“讀”多於“寫”的應用程序中尤其地高性能,因爲“寫”會導致所有的服務器間同步狀態。(“讀”多於“寫”是協調服務的典型場景。)

五 ZooKeeper 集羣角色介紹

最典型集羣模式: Master/Slave 模式(主備模式)。在這種模式中,通常 Master服務器作爲主服務器提供寫服務,其他的 Slave 服務器從服務器通過異步複製的方式獲取 Master 服務器最新的數據提供讀服務。

但是,在 ZooKeeper 中沒有選擇傳統的 Master/Slave 概念,而是引入了Leader、Follower 和 Observer 三種角色。如下圖所示

ZooKeeper 集羣中的所有機器通過一個 Leader 選舉過程來選定一臺稱爲 “Leader” 的機器,Leader 既可以爲客戶端提供寫服務又能提供讀服務。除了 Leader 外,Follower 和 Observer 都只能提供讀服務。Follower 和 Observer 唯一的區別在於 Observer 機器不參與 Leader 的選舉過程,也不參與寫操作的“過半寫成功”策略,因此 Observer 機器可以在不影響寫性能的情況下提升集羣的讀性能。

六 ZooKeeper &ZAB 協議&Paxos算法

6.1 ZAB 協議&Paxos算法

Paxos 算法應該可以說是 ZooKeeper 的靈魂了。但是,ZooKeeper 並沒有完全採用 Paxos算法 ,而是使用 ZAB 協議作爲其保證數據一致性的核心算法。另外,在ZooKeeper的官方文檔中也指出,ZAB協議並不像 Paxos 算法那樣,是一種通用的分佈式一致性算法,它是一種特別爲Zookeeper設計的崩潰可恢復的原子消息廣播算法。

6.2 ZAB 協議介紹

ZAB(ZooKeeper Atomic Broadcast 原子廣播) 協議是爲分佈式協調服務 ZooKeeper 專門設計的一種支持崩潰恢復的原子廣播協議。 在 ZooKeeper 中,主要依賴 ZAB 協議來實現分佈式數據一致性,基於該協議,ZooKeeper 實現了一種主備模式的系統架構來保持集羣中各個副本之間的數據一致性。

6.3 ZAB 協議兩種基本的模式:崩潰恢復和消息廣播

關於 ZAB 協議&Paxos算法 需要講和理解的東西太多了,說實話,筆主到現在不太清楚這倆兄弟的具體原理和實現過程。推薦閱讀下面兩篇文章:

  • 圖解 Paxos 一致性協議(http://blog.xiaohansong.com/2016/09/30/Paxos/)
  • Zookeeper ZAB 協議分析(http://blog.xiaohansong.com/2016/08/25/zab/)

關於如何使用 zookeeper 實現分佈式鎖,可以查看下面這篇文章:

10分鐘看懂!基於Zookeeper的分佈式鎖(https://blog.csdn.net/qiangcuo6087/article/details/79067136)

六 總結

通過閱讀本文,想必大家已從 ①ZooKeeper的由來。 -> ②ZooKeeper 到底是什麼 。-> ③ ZooKeeper 的一些重要概念(會話(Session)、 Znode、版本、Watcher、ACL)-> ④ZooKeeper 的特點。 -> ⑤ZooKeeper 的設計目標。-> ⑥ ZooKeeper 集羣角色介紹 (Leader、Follower 和 Observer 三種角色)-> ⑦ZooKeeper &ZAB 協議&Paxos算法。 這七點了解了 ZooKeeper 。

號外:

全國地圖poi數據下載 http://www.poi58.com

參考

  • 《從Paxos到Zookeeper 》
  • https://cwiki.apache.org/confluence/display/ZOOKEEPER/ProjectDescription
  • https://cwiki.apache.org/confluence/display/ZOOKEEPER/Index
  • https://www.cnblogs.com/raphael5200/p/5285583.html
  • https://zhuanlan.zhihu.com/p/30024403
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章