1. 程式人生 > >Hadoop從入門到放棄系列------ZooKeeper

Hadoop從入門到放棄系列------ZooKeeper

一、ZooKeeper的由來

 ZooKeeper最早起源於雅虎研究院的一個研究小組,其宗旨就是解決分散式系統中的協調問題,並且自身無單點風險。

再說下“ZooKeeper”這個名字由來的趣聞,在立項初期,考慮到之前內部很多專案都是使用動物的名字來命名的(例如Pig,Hive等),雅虎的工程師希望給這個專案也取一個動物的名字。時任研究院的首席科學家RaghuRamakrishnan開玩笑地說:“在這樣下去,我們這兒就變成動物園了!”此話一出,大家紛紛表示就叫動物園管理員吧一一一因為各個以動物命名的分散式元件放在一起,雅虎的整個分散式系統看上去就像一個大型的動物園了,而ZooKeeper正好要用來進行分散式環境的協調一一於是,ZooKeeper的名字也就由此誕生了。

二、ZooKeeper 到底是什麼

 ZooKeeper是一個開源的分散式協調服務,最初在“Yahoo!”上構建,是Google Chubby的開源實現。分散式應用程式可以基於 ZooKeeper 實現諸如資料釋出/訂閱、負載均衡、命名服務、分散式協調/通知、叢集管理、Master 選舉、配置維護、分散式同步、分散式鎖和分散式佇列等功能。

三、ZooKeeper 的一些重要概念

 1、叢集角色

ZooKeeper叢集包括三種角色:Leader,Follower,Observer,如下圖

Leader由除Observer外的所有節點選舉產生,既可以為客戶端提供寫服務又能提供讀服務。Follower 和 Observer 都只能提供讀服務。

Follower 和 Observer 唯一的區別在於 Observer 機器不參與 Leader 的選舉過程,也不參與寫操作的“過半寫成功”策略,因此 Observer 機器可以在不影響寫效能的情況下提升叢集的讀效能。

2、會話

會話(Session)就是一個客戶端與伺服器之間的一個TCP長連線,客戶端和伺服器的一切互動都是通過這個長連線進行的;當客戶端連線斷開時,只要在 SessionTimeout 規定的時間內能夠重新連線上叢集中任意一臺伺服器,那麼之前建立的會話仍然有效。sessionID是會話的全域性唯一標識。

3、節點

節點在ZeeKeeper中包含兩層含義:

1、叢集中的一臺機器,我們稱為機器節點;

2、ZooKeeper資料模型中的資料單元,我們成為資料節點(ZNode)。

Zookeeper將所有資料儲存在記憶體中,資料模型是一棵樹(Znode Tree),由斜槓(/)的進行分割的路徑,就是一個Znode,例如/app1/p_1。每個上都會儲存自己的資料內容,同時還會儲存一系列屬性資訊。

在Zookeeper中,node可以分為持久節點和臨時節點兩類。

持久節點:一旦這個ZNode被建立了,除非主動進行ZNode的移除操作,否則這個ZNode將一直儲存在Zookeeper上。

臨時節點:它的生命週期和客戶端會話繫結,一旦客戶端會話失效,那麼這個客戶端建立的所有臨時節點都會被移除。

4、版本

ZooKeeper為每一個ZNode節點維護一個叫做Stat的資料結構,在Stat中維護了節點相關的三個版本:

1、當前ZNode的版本version

2、當前ZNode子節點的版本cversion

3、當前ZNode的ACL(Access Control Lists)版本aversion

5、監聽器

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

6、ACL

Zookeeper採用ACL(Access Control Lists)策略來進行許可權控制,類似於 UNIX 檔案系統的許可權控制。Zookeeper 定義瞭如下5種許可權。

CREATE:建立子節點的許可權

READ:獲取節點資料和子節點列表的許可權

WRITE:更新節點資料的許可權

DELETE:刪除子節點的許可權

ADMIN:設定節點ACL的許可權

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

四、ZooKeeper 的特點

1、順序一致性

從同一個客戶端發起的事務請求,最終將會嚴格按照其發起順序被應用到ZooKeeper中

2、原子性

所有事物請求的處理結果在整個叢集中所有機器上的應用情況是一致的,即,要麼整個叢集中所有機器都成功應用了某一事務,要麼都沒有應用,一定不會出現叢集中部分機器應用了該事務,另外一部分沒有應用的情況。

3、單一檢視(最終一致性)

無論客戶端連線的是哪個ZooKeeper Server,其看到的服務端資料模型都是一致的。

4、可靠性

ZooKeeper叢集Leader、Follower機制

5、實時性

準確說應該是準實時,通過效能會彌補一定的實時性。

五、ZooKeeper的典型應用場景

1、資料釋出與訂閱

釋出/訂閱模式是一對多的關係,多個訂閱者物件同時監聽某一主題物件,這個主題物件在自身狀態發生變化時會通知所有的訂閱者物件。使它們能自動的更新自己的狀態。釋出/訂閱可以使得釋出方和訂閱方獨立封裝、獨立改變。當一個物件的改變需要同時改變其他物件,而且它不知道具體有多少物件需要改變時可以使用釋出/訂閱模式。釋出/訂閱模式在分散式系統中的典型應用有配置管理服務發現、註冊

配置管理是指如果叢集中的機器擁有某些相同的配置並且這些配置資訊需要動態的改變,我們可以使用釋出/訂閱模式把配置做統一集中管理,讓這些機器格子各自訂閱配置資訊的改變,當配置發生改變時,這些機器就可以得到通知並更新為最新的配置。

服務發現、註冊是指對叢集中的服務上下線做統一管理。每個工作伺服器都可以作為資料的釋出方向叢集註冊自己的基本資訊,而讓某些監控伺服器作為訂閱方,訂閱工作伺服器的基本資訊,當工作伺服器的基本資訊發生改變如上下線、伺服器角色或服務範圍變更,監控伺服器可以得到通知並響應這些變化。

釋出/訂閱系統一般有兩種設計模式,分別是推(Push)模式和拉(Pull)模式。

推模式:服務端主動將資料更新發送給所有訂閱的客戶端。

拉模式:客戶端通過採用定時輪詢拉取。

ZooKeeper採用的是推拉相結合的方式:客戶端向服務端註冊自己需要關注的節點,一旦該節點的資料發生變更,那麼服務端就會向相應的客戶端傳送Watcher事件通知,客戶端接收到這個訊息通知之後,需要主動到服務端獲取最新的資料。

2、布通知/協調

ZooKeeper 中特有watcher註冊與非同步通知機制,能夠很好的實現分散式環境下不同系統之間的通知與協調,實現對資料變更的實時處理。使用方法通常是不同系統都對 ZK上同一個znode進行註冊,監聽znode的變化(包括znode本身內容及子節點的),其中一個系統update了znode,那麼另一個系統能夠收到通知,並作出相應處理。

1、另一種心跳檢測機制:檢測系統和被檢測系統之間並不直接關聯起來,而是通過ZK上某個節點關聯,大大減少系統耦合。

2. 另一種系統排程模式:某系統有控制檯和推送系統兩部分組成,控制檯的職責是控制推送系統進行相應的推送工作。管理人員在控制檯作的一些操作,實際上是修改 了ZK上某些節點的狀態,而zk就把這些變化通知給他們註冊Watcher的客戶端,即推送系統,於是,作出相應的推送任務。

3. 另一種工作彙報模式:一些類似於任務分發系統,子任務啟動後,到zk來註冊一個臨時節點,並且定時將自己的進度進行彙報(將進度寫回這個臨時節點),這樣任務管理者就能夠實時知道任務進度。

總之,使用zookeeper來進行分散式通知和協調能夠大大降低系統之間的耦合。

3、分散式鎖

分散式鎖,這個主要得益於ZooKeeper為我們保證了資料的強一致性,即使用者只要完全相信每時每刻,ZK叢集中任意節點(一個ZK server)上的相同znode的資料是一定是相同的。鎖服務可以分為兩類,一個是保持獨佔,另一個是控制時序。

保持獨佔,就是所有試圖來獲取這個鎖的客戶端,最終只有一個可以成功獲得這把鎖。通常的做法是把zk上的一個znode看作是一把鎖,通過create znode的方式來實現。所有客戶端都去建立 /distribute_lock 節點,最終成功建立的那個客戶端也即擁有了這把鎖。

控制時序,就是所有檢視來獲取這個鎖的客戶端,最終都是會被安排執行,只是有個全域性時序了。做法和上面基本類似,只是這裡 /distribute_lock 已經預先存在,客戶端在它下面建立臨時有序節點(這個可以通過節點的屬性控制:CreateMode.EPHEMERAL_SEQUENTIAL來指定)。ZK的父節點(/distribute_lock)維持一份sequence,保證子節點建立的時序性,從而也形成了每個客戶端的全域性時序。

4、Master選舉

在分散式環境中,相同的業務應用分佈在不同的機器上,有些業務邏輯(例如一些耗時的計算,網路I/O處理),往往只需要讓整個叢集中的某一臺機器進行執行, 其餘機器可以共享這個結果,這樣可以大大減少重複勞動,提高效能,於是這個master選舉便是這種場景下的碰到的主要問題。

利用ZooKeeper的強一致性,能夠保證在分散式高併發情況下節點建立的全域性唯一性,即:同時有多個客戶端請求建立 /currentMaster 臨時節點,最終一定只有一個客戶端請求能夠建立成功,成功建立該節點的客戶端所在的機器就成為了 Master。同時,其他沒有成功建立該節點的客戶端,都會在該節點上註冊一個子節點變更的 Watcher,用於監控當前 Master 機器是否存活,一旦發現當前的Master掛了,那麼其他客戶端將會重新進行 Master 選舉, 這樣就實現了 Master 的動態選舉。