Zookeeper概述
Zookeeper是一個開放源碼的分布式應用程序協調服務,是 Google的Chubby一個開源的實現,是 Hadoop和 HBASE的重要組件。主要解決分布式應用一致性問題。
1.分布式應用
分布式應用可以在給定時間(同時)在網絡中的多個系統上運行,通過協調它們以快速有效的方式完成特定任務。通常來說,對於復雜而耗時的任務,非分布式應用(運行在單個系統中)需要幾個小時才能完成,而分布式應用通過使用所有系統涉及的計算能力可以在幾分鍾內完成。
通過將分布式應用配置為在更多系統上運行,可以進一步減少完成任務的時間。分布式應用正在運行的一組系統稱為集群,而在集群中運行的每台機器被稱為節點。
分布式應用有兩部分, Server(服務器) 和 Client(客戶端) 應用程序。服務器應用程序實際上是分布式的,並具有通用接口,以便客戶端可以連接到集群中的任何服務器並獲得相同的結果。 客戶端應用程序是與分布式應用進行交互的工具。
分布式應用的優點
- 可靠性 - 單個或幾個系統的故障不會使整個系統出現故障。
- 可擴展性 - 可以在需要時增加性能,通過添加更多機器,在應用程序配置中進行微小的更改,而不會有停機時間。
- 透明性 - 隱藏系統的復雜性,並將其顯示為單個實體/應用程序。
分布式應用的挑戰
- 競爭條件 - 兩個或多個機器嘗試執行特定任務,實際上只需在任意給定時間由單個機器完成。例如,共享資源只能在任意給定時間由單個機器修改。
- 死鎖 - 兩個或多個操作等待彼此無限期完成。
- 不一致 - 數據的部分失敗。
分布式應用程序提供了很多好處,但它們也拋出了一些復雜和難以解決的挑戰。ZooKeeper框架提供了一個完整的機制來克服所有的挑戰。
2. Zookeeper簡介
Zookeeper是一個能夠高效開發和維護分布式的開放源碼的應用協調服務。是Google的 Chubby一個開源的實現,是 Hadoop和 HBASE的重要組件。Zookeeper是一個為分布式應用提供一致性服務的軟件,提供的功能包括維護配置信息、名字服務、分布式同步、組服務等。ZooKeeper框架最初是在“Yahoo!"上構建的,用於以簡單而穩健的方式訪問他們的應用程序。 后來,Apache ZooKeeper成為Hadoop,HBase和其他分布式框架使用的有組織服務的標准。
首先我們對上一個段落做一個解釋。
- Zookeeper是一個開放源代碼的軟件。
- Zookeeper是一個管理“分布式應用程序”的軟件。什么是分布式應用程序服務?我們知道,Hadoop中的組件,如hdfs、MapReduce/yarn、hbase、double、kafka都是分布式服務。如MapReduce就是一個分布式服務,MapReduce會將所做的工作分發給Hadoop集群中的多台服務器共同實現。如何對分布式服務做協調,管理這些運行在不同電腦上的任務?就需要一個對分布式應用程序做協調的服務,這就是Zookeeper的工作。
- Zookeeper可以實現對分布式應用程序做一致性服務,什么是一致性服務?比如我們對A服務器上的一個數據進行了修改,這個數據同時在D服務器和M服務器有兩個備份,這時就要對D服務器和M服務器有兩個備份都進行修改,這就是一致性服務。Zookeeper就可以實現這么一個一致性服務。
- Zookeeper實現的強一致性服務。一致性服務分為3類,分別是:
- 強一致性:a發生變化,b立刻就發生變化
- 弱一致性:a發生變化,b過一會會發生變化
- 最終一致性:a發生變化,b最終也會發生變化
Zookeeper可以實現立刻的數據一致性,即強一致性。
大家知道,Hadoop生態系統中的組件,都喜歡起動物的名稱。如Hadoop、Hive、Pig等。而Zookeeper中文意思是動物園管理員,就是管理Hadoop生態系統。
5. ZooKeeper的好處
以下是使用ZooKeeper的好處:
- 簡單的分布式協調過程
- 同步 - 服務器進程之間的相互排斥和協作。此過程有助於Apache HBase進行配置管理。
- 有序的消息
- 序列化 - 根據特定規則對數據進行編碼。確保應用程序運行一致。這種方法可以在MapReduce中用來協調隊列以執行運行的線程。
- 可靠性
- 原子性 - 數據轉移完全成功或完全失敗,但沒有事務是部分的。
3 .Zookeeper的選舉機制
看看下面的圖表。它描述了ZooKeeper的“客戶端-服務器架構”。
配置多個實例共同構成一個Zookeeper集群對外提供服務以達到水平擴展的目的,集群中的每一台電腦都稱為服務器(Server),每個服務器上的數據是相同的,每一個服務器均可以對外提供讀和寫的服務,這點和redis是相同的,即對客戶端來講每個服務器都是平等的。zookeeper集群一般需要奇數台服務器,為什么是奇數台服務器?因為我們需要通過選舉機制選出領導者(leader),所以必須是奇數台服務器。
Zookeeper提供了三種選舉機制:
- LeaderElection
- AuthFastLeaderElection
- FastLeaderElection
默認的算法是FastLeaderElection,所以這篇主要分析它的選舉機制。
客戶端(client)是請求發起方。服務器分為不同的角色,有領導者(leader),也有學習者(learner)。角色的不同是在選舉中產生的,下面是選舉的流程。
目前有5台服務器,每台服務器均沒有數據,它們的編號分別是A,B,C,D,E按編號依次啟動,它們的選擇舉過程如下:
- 服務器A啟動,給自己投票,然后發投票信息,由於其它機器還沒有啟動所以它收不到反饋信息,服務器A的狀態一直屬於Looking(選舉狀態)。
- 服務器B啟動,給自己投票,同時與之前啟動的服務器A交換結果,由於服務器B的編號大所以服務器B勝出,但此時投票數沒有大於半數,所以兩個服務器的狀態依然是Looking(選舉狀態)。
- 服務器C啟動,給自己投票,同時與之前啟動的服務器A,B交換信息,由於服務器C的編號最大所以服務器C勝出,此時投票數正好大於半數,所以服務器C成為領導者(Leader),服務器A,B成為小弟。
- 服務器D啟動,給自己投票,同時與之前啟動的服務器A,B,C交換信息,盡管服務器D的編號大,但之前服務器C已經勝出,所以服務器D只能成為小弟。
- 服務器E啟動,后面的邏輯同服務器E成為小弟。
這里的小弟就是學習者(learner)。學習者(learner)分為兩類,能夠參與投票的就是跟隨者(follower),否則就是觀察者(observer)。
服務器有以下狀態。
- LOOKING:競選狀態。
- FOLLOWING:隨從狀態,同步leader狀態,參與投票。
- OBSERVING:觀察狀態,同步leader狀態,不參與投票。
- LEADING:領導者狀態。
下面是選舉的簡易流程圖。
以下是選舉狀態圖
描述Leader選擇過程中的狀態變化,這是假設全部實例中均沒有數據,假設服務器啟動順序分別為:A,B,C。
角色 |
描述 |
||
服務器(Server) |
領導者(Leader) |
服務器節點,負責進行投票的發起和決議,更新系統狀態。 |
|
學習者(Learner) |
跟隨者(Follower) |
服務器節點,用於接收客戶端請求並向客戶端返回結果,在選舉過程中能參與投票。 |
|
觀察者(Observer) |
當集群節點數目逐漸增大為了支持更多的客戶端,需要增加更多Server,然而Server增多,投票階段延遲增大,影響性能。為了權衡伸縮性和高吞吐率,引入Observer。 服務器節點,可以接收客戶端連接,將寫請求轉發給Leader節點。但Observer不能參與投票,只同步Leader的狀態。Observer的目的是為了擴展系統,提高讀取速度。 |
||
客戶端(Client) |
請求發起方 |
4. Zookeeper的讀寫機制
Zookeeper是分布式應用程序的協調程序。分布式應用程序運行在集群上,客戶端對一台服務器的請求完成后修改了數據並將數據同步到其他備份,並且需要將結果告知集群中所有電腦,這個由分布式應用程序自身實現嗎?可以,但是也可以由另一個協調程序完成這個功能,Zookeeper就是這么一個協調程序。下面我們介紹以下Zookeeper寫流程。下面我們見下圖。
![]() |
客戶端首先和一個Server或者Observer(可以認為是一個Server的代理)通信,發起寫請求,然后Server將寫請求轉發給Leader,Leader再將寫請求轉發給其他Server,Server在接收到寫請求后寫入數據並回應Leader,Leader在接收到大多數寫成功回應后,認為數據寫成功,回應Client。
|
Zookeeper讀取由特定連接的Server在內部執行,因此不需要與集群進行交互。
5. Zookeeper的數據模型
Zookeeper的數據保存在一個類似於文件系統的一個樹形結構中,每個數據節點只能攜帶少量的數據。為什么只能攜帶少量的數據呢?因為Zookeeper用於進行協調服務的,所以不需要攜帶大量數據。
每個數據節點(樹中的每一個分支節點或者葉子節點)稱之為znode。每一個znode節點既是目錄又是文件(是文件的含義是它可以帶少量數據,是目錄的含義是它有可能還有子目錄),這和我們普通看到的文件系統不一樣。
每個目錄在zookeeper中叫做znode,並且其有一個唯一的路徑標識,如/services/myservice/servers/stuidname1
- znode有兩種類型,短暫的(ephemeral: 斷開連接自己刪除)和持久的(ersistent: 斷開連接不刪除);
- znode可以包含數據和子znode(ephemeral類型的節點不能有子znode);
- znode中的數據可以有多個版本,比如某一個znode下存有多個數據版本,那么查詢這個路徑下的數據需帶上版本;
創建znode時設置順序標識,znode名稱后會附加一個值,順序號是一個單調遞增的計數器,由父節點維護 。
如存一個/stu/name值mike,會對路徑上加序列化,如/name000001
再存一個/stu/name值jack,會對路徑上加序列化, 如/name000002
上面的znode就有兩個版本
- 客戶端應用可以在znode上設置監視器(Watcher)。
- znode不支持部分讀寫,而是一次性完整讀寫
- znode的類型在創建時確定並且之后不能再修改;
- ephemeral znode的客戶端會話結束時,zookeeper會將該ephemeral znode刪除,ephemeral znode不可以有子節點;
- persistent znode不依賴於客戶端會話,只有當客戶端明確要刪除該persistent znode時才會被刪除;
Zookeeper以節點的方式存儲一些關鍵信息,默認情況下,所有應用都可以讀寫任何節點,在復雜的應用中,這不太安全,Zookeeper通過ACL(Access Controll List)機制來解決訪問權限問題。
總體來說,Zookeeper的節點有5種ACL(Access Controller List)權限:
- CREATE 允許創建Child Nodes
- READ 允許獲取ZNode的數據,以及該節點的孩子列表
- WRITE 可以修改ZNode的數據
- DELETE 可以刪除一個孩子節點
- ADMIN 可以設置權限
這5種權限簡寫為crwda(即:每個單詞的首字符縮寫)。注意這5種權限中,delete是指對子節點的刪除權限,其它4種權限指對自身節點的操作權限。
6. Zookeeper的監聽機制
Zookeeper的節點是可以被監控,目錄中存儲數據的修改、子節點目錄的變化,都可以觸發事件並通知監聽的客戶端,這是 Zookeeper重要的特性。通過此特性可以實現的功能個監聽事件是一個有配置的集中管理、集群管理、分布式鎖等。監聽機制官方說明為次性的監聽器,當被設置了監聽的數據發生變化時,服務器就會將這個改變發送給負責設置 Watch的客戶端。
ZooKeeper中的Watch是只能觸發一次。也就是說,如果客戶端在指定的ZNode設置了Watch,如果該ZNode數據發生變更,ZooKeeper會發送一個變更通知給客戶端,同時觸發設置的Watch事件。如果ZNode數據又發生了變更,客戶端在收到第一次通知后沒有重新設置該ZNode的Watch,則ZooKeeper就不會發送一個變更通知給客戶端。
Zookeeper的特點是
- 一次性觸發
- 事件觸發后發給客戶端。
- 數據被設置 Watch