1. 程式人生 > >Zookeeper技術分享

Zookeeper技術分享

超過 相同 per 可擴展 特定 不同的 好的 而是 信息保存

內容整理自組內分享PPT

技術分享圖片

一.概述

ZooKeeper 遵循一個簡單的客戶端-服務器模型,其中客戶端 是使用服務的節點(即機器),而服務器 是提供服務的節點。ZooKeeper 服務器的集合形成了一個 ZooKeeper 集合體(ensemble)。在任何給定的時間內,一個 ZooKeeper 客戶端可連接到一個 ZooKeeper 服務器。每個 ZooKeeper 服務器都可以同時處理大量客戶端連接。每個客戶端定期發送 ping 到它所連接的 ZooKeeper 服務器,讓服務器知道它處於活動和連接狀態。被詢問的 ZooKeeper 服務器通過 ping 確認進行響應,表示服務器也處於活動狀態。如果客戶端在指定時間內沒有收到服務器的確認,那麽客戶端會連接到集合體中的另一臺服務器,而且客戶端會話會被透明地轉移到新的 ZooKeeper 服務器。

Zookeeper的節點兼具文件和目錄兩種特點,除此之外,Znode還有以下特性:

1.Znode可以被監控

2.Znode有版本

3.每個Znode存儲的數據大小至多1M左右

技術分享圖片

二.節點的分類

ZooKeeper中的節點有兩種,分別為臨時節點和永久節點。節點的類型在創建時即被確定,並且不能改變:

① 臨時節點:該節點的生命周期依賴於創建它們的會話。一旦會話(Session)結束,臨時節點將被自動刪除,當然可以也可以手動刪除。雖然每個臨時的Znode都會綁定到一個客戶端會話,但他們對所有的客戶端還是可見的。另外,ZooKeeper的臨時節點不允許擁有子節點。

② 永久節點:該節點的生命周期不依賴於會話,並且只有在客戶端顯示執行刪除操作的時候,他們才能被刪除。

三.讀寫分離

當客戶端請求讀取特定 znode 的內容時,讀取操作是在客戶端所連接的服務器上進行的。因此,由於只涉及集合體中的一個服務器,所以讀取是快速和可擴展的。然而,為了成功完成寫入操作,要求 ZooKeeper 集合體的嚴格意義上的多數節點都是可用的。在啟動 ZooKeeper 服務時,集合體中的某個節點被選舉為領導者。當客戶端發出一個寫入請求時,所連接的服務器會將請求傳遞給領導者。此領導者對集合體的所有節點發出相同的寫入請求。如果嚴格意義上的多數節點(也被稱為法定數量(quorum))成功響應該寫入請求,那麽寫入請求被視為已成功完成。然後,一個成功的返回代碼會返回給發起寫入請求的客戶端。

技術分享圖片

四.數據寫入與節點選舉

1.節點的角色:

(1) 投票Server:Leader、Follower

(2) 非投票Server:Observer:Observer的作用同Follower類似,唯一區別就是它不參與選主過程,為什麽引入這個角色後文會講到。

2.寫入數據的流程:

來自Client的所有寫請求,都要轉發給ZK服務中唯一的Server—Leader,由Leader根據該請求發 起一個Proposal。然後,其他的Server對該Proposal進行Vote。之後,Leader對Vote進行收集,當Vote數量過半時 Leader會向所有的Server發送一個通知消息。最後,當Client所連接的Server收到該消息時,會把該操作更新到內存中並對Client 的寫請求做出回應。當znode改變的時候服務器監聽被觸發,會回調客戶端,客戶端可以在回調中做自己需要處理的邏輯 ,以下這些操作會觸發watcher:create、delete、setData、setACL。

3.為什麽引入Observer:

ZooKeeper 服務器在上述的寫入數據流程中實際扮演了兩個職能。它們一方面從客戶端接受連接與操作請求,另一方面對操作結果進行投票。這兩個職能在 ZooKeeper集群擴展的時候彼此制約。例如,當我們希望增加 ZK服務中Client數量的時候,那麽我們就需要增加Server的數量,來支持這麽多的客戶端。然而,我們可以發 現,增加服務器的數量,則增加了對協議中投票過程的壓力。因為Leader節點必須等待集群中過半Server響應投票,於是節點的增加使得部分計算機運 行較慢,從而拖慢整個投票過程的可能性也隨之提高,寫操作也會隨之下降。這正是我們在實際操作中看到的問題——隨著 ZooKeeper 集群變大,寫操作的吞吐量會下降

我們不得不在增加Client數量的期望和我們希望保持較好吞吐性能的期望間進行權衡。要打破這一耦合關系,我們引入了不參與投票的服務器,稱為Observer。 Observer可以接受客戶端的連接,並將寫請求轉發給Leader節點。但是,Leader節點不會要求 Observer參加投票。相反,Observer不參與投票過程,僅僅在上述第3歩那樣,和其他服務節點一起得到投票結果。

(zookeeper中規定只有當多余一半的節點同步完成整個write操作才算完成。也就是說可能會有少於一半的數據不是新數據,因此zookeeper中數據不是強一致性而是最終一致性。)

技術分享圖片

上圖縱軸是單一客戶端能夠發出的每秒鐘同步寫操作的數量。橫軸是 ZooKeeper 集群的尺寸。藍色的是每個服務器都是投票Server的情況,而綠色的則只有三個是投票Server,其它都是 Observer。從圖中我們可以看出,我們在擴充 Observer時寫性能幾乎可以保持不便。但是,如果擴展投票Server的數量,寫性能會明顯下降,顯然 Observers 是有效的。這個簡單的擴展,給 ZooKeeper 的可伸縮性帶來了全新的景象。我們現在可以加入很多 Observer 節點,而無須擔心嚴重影響寫吞吐量。Observer即使fail掉也不影響zk集群服務。

由於上述這些條件,Zookeeper能夠保證:

1.順序一致性來自於客戶端的更新,根據發送的先後被順序實施。

2.唯一的系統映像 client不論連接到哪個Server,展示給它都是同一個視圖,這是zookeeper最重要的性能。

3.可靠性 具有簡單、健壯、良好的性能,如果消息m被一臺服務器接受,那麽它將被所有的服務器接受。

五.節點的刪除

 ZooKeeper類提供了一個delete()方法,該方法有兩個參數: 1. 路徑 2. 版本號

如果所提供的路徑與版本號與某個znode一致,ZooKeeper會刪除這個znode。這是一種樂觀鎖,使客戶端能夠檢測出對znode的修改沖突。通過將版本號設置為-1,可以繞過這個版本檢測機制,不管znode的版本號是什麽而直接將其刪除。

ZooKeeper不支持遞歸的刪除操作,因此在刪除父節點之前必須先刪除子節點。

五.舉例Zookeeper提供的服務

1.集群管理

集群內的所有機器在 Zookeeper 上創建一個 EPHEMERAL 類型的目錄節點,然後每個 Server 在它們創建目錄節點的父目錄節點上調用 getChildren(String path, boolean watch) 方法並設置 watch 為 true,由於是 EPHEMERAL 目錄節點,當創建它的 Server 死去,這個目錄節點也隨之被刪除,所以 Children 將會變化,這時 getChildren上的 Watch 將會被調用,所以其它 Server 就知道已經有某臺 Server 死去了。新增 Server 也是同樣的原理。

技術分享圖片

2.配置管理

分布式應用需要多臺Server 運行,但是它們運行的應用系統的某些配置項是相同的,如果要修改這些相同的配置項,那麽就必須同時修改每臺運行這個應用系統的Server,這樣非常麻煩而且容易出錯。可以將配置信息保存在 Zookeeper 的某個目錄節點中,然後將所有需要修改的應用機器監控配置信息的狀態,一旦配置信息發生變化,每臺應用機器就會收到 Zookeeper 的通知,然後從 Zookeeper 獲取新的配置信息應用到系統中。

技術分享圖片

3.分布式鎖

技術分享圖片

分布式鎖在一組進程之間提供了一種互斥機制。在任何時刻,在任何時刻只有一個進程可以持有鎖。分布式鎖可以在大型分布式系統中實現領導者選舉,在任何時間點,持有鎖的那個進程就是系統的領導者。另外,請註意,這裏所說的領導者選舉指的是利用zk的特性幫助分布式應用選舉領導,上文所說的是ZK內部的領導選舉。

流程:每個需要獲取鎖的進程在ZK中註冊一個臨時而且順序的Znode(EPHEMERAL_SEQUENTIAL類型),每個順序Znode內部會維護一個zxid(順序號),zxid是一個全局變量,隨著Znode的每一次改變而遞增,在任何時間點,zxid最小的進程將持有鎖。刪除節點即可釋放鎖,如果客戶端進程死亡,對應的短暫Znode也會被刪除。當leader掛掉的時候,剩余的flower選擇zxid最大的節點作為新的leader。

六.Zookeeper的安裝

1.單機模式:Zookeeper只運行在一臺服務器上,適合測試環境;

2.偽集群模式:就是在一臺物理機上運行多個Zookeeper 實例;

在一臺機器上部署了3個server,需要註意的是在集群偽集群模式下我們使用的每個配置文檔模擬一臺機器,也就是說單臺機器及上運行多個Zookeeper實例。但是,必須保證每個配置文檔的各個端口號不能沖突,除了clientPort不同之外,Zookeeper安裝目錄也不能相同。另外,還要在dataDir所對應的目錄中創建myid文件來指定對應的Zookeeper服務器實例,不同實例需要有不同的端口號。

3.集群模式(通常使用的模式):Zookeeper運行於一個集群上,適合生產環境,這個計算機集群被稱為一個“集合體”(ensemble)

4.配置文件中的一些配置項:

  client:監聽客戶端連接的端口

  tickTime:基本事件單元,這個時間是作為Zookeeper服務器之間或客戶端與服務器之間維持心跳的時間間隔,每隔tickTime時間就會發送一個心跳;

  最小的session過期時間為2倍tickTime

  maxClientCnxns:這個操作將限制連接到Zookeeper的客戶端數量,並限制並發連接的數量,通過IP來區分不同的客戶端。

  initLimit:此配置表示,允許follower連接並同步到Leader的初始化連接時間,以tickTime為單位。當初始化連接時間超過該值,則表示連接失敗。

  syncLimit:此配置項表示Leader與Follower之間發送消息時,請求和應答時間長度。如果follower在設置時間內不能與leader通信,那麽此follower將會被丟棄。

server.A=B:C:D:A:其中 A 是一個數字,表示這個是服務器的編號;B:是這個服務器的 ip 地址;C:Leader選舉的端口;D:Zookeeper服務器之間的通信端口。

參考資料:

http://www.douban.com/note/208430424/
rdc.taobao.com/blog/cs/?p=162
http://www.cnblogs.com/lpshou/archive/2013/06/14/3136738.html
http://my.oschina.net/u/658658/blog/474277
http://www.cnblogs.com/sunddenly/p/4033574.html
http://www.ibm.com/developerworks/cn/data/library/bd-zookeeper/
https://www.ibm.com/developerworks/cn/opensource/os-cn-zookeeper/

Zookeeper技術分享