[Zookeeper研究]一 Zookeeper技術簡介

最近的項目中使用到了Zookeeper、Kafka以及Storm。仔細研究了一下,以爲這幾個開源項目對於搞分佈式的人來講是很是有用的,因此想把本身的一點心得體會總結一下,但願能對你們有所幫助。html

首先從Zookeeper開始。這一節主要是介紹一下Zookeeper的背景和架構node

zookeeper是一個開源分佈式的服務,它提供了分佈式協做,分佈式同步,配置管理等功能. 它實現的功能與google的chubby基本一致。apache

Zookeeper的官方文檔對它的設計實現有很詳細的描述,下面咱們來簡單介紹一下。session

一. Zookeeper的設計目標數據結構

     1. Simple。 ZooKeeper的命名空間組織結構相似文件系統,分佈式系統能夠基於它進行協做。Zookeeper中的每個節點都是一個znode,它相似於文件系統中的文件或文件夾。通用的文件系統通常都是設計用來存儲數據,而Zookeeper的數據都是保存在memory中的,這也意味這ZooKeeper可以有很高的throughput和很低的延遲。架構

  ZooKeeper的實現主要考慮的是高性能、高可用性以及嚴格的順序訪問。 高性能意味着它能夠被用在大型的分佈式系統中;高可用性是指使用ZooKeeper集羣可以避免單點故障;嚴格的順序意味着ZooKeeper的客戶端能夠實現複雜的同步功能。分佈式

  2. replicated。像不少分佈式系統同樣,ZooKeeper的數據會被拷貝到一個集羣中的多臺機器上,這些機器組成一個ZooKeeper集羣,以下圖所示:函數

  組成ZooKeeper集羣服務的Server都要獲知彼此的存在。它們在內存中保存了當前ZooKeeper服務數據的最新鏡像,同時每隔一段時間會持久化保存這些鏡像數據以及transaction日誌。這些數據能夠被用來恢復ZooKeeper服務。只要大部分的ZooKeeper Server都正常,ZooKeeper服務就是可用的。oop

  每一個客戶端都只會鏈接到一個ZooKeeper Server,客戶端維護了一個跟Server的TCP鏈接,能夠經過這個鏈接來發送請求、獲取數據、獲取監聽事件以及發送心跳信息。若是TCP鏈接斷掉,客戶端會嘗試鏈接到其它Server。性能

  3. Ordered。ZooKeeper爲每一次update都關聯一個number,它反映了全部ZooKeeper transactions的順序。之後的操做能夠基於該順序實現更高層次的抽象,好比分佈式同步鎖等。

  4. Fast。ZooKeeper在以讀操做爲主的場景中尤爲快。ZooKeeper應用能夠運行在成百上千臺機器中,當讀寫操做比爲10:1時它表現的最好。

二. ZooKeeper的數據模型和層次式的命名空間。

  ZooKeeper提供的命名空間很像一個標準的文件系統,以下圖所示,它的名字是一系列由"/"分隔的路徑。ZooKeeper命名空間中的每個節點都由一個路徑指定。

 

三. ZooKeeper節點以及ephemeral節點

  同文件系統不一樣的是,每個ZooKeeper的節點都既能夠存儲數據也能夠含有子節點。普通文件系統中,只有文件夾能夠有子文件或子目錄,文件只能用來存儲數據。因此這裏ZooKeeper就好像是文件系統容許一個文件能夠有文件夾的功能。ZooKeeper是被設計用來存儲一些協做數據的,好比說狀態信息、配置信息、位置信息等,因此一般每一個節點存儲的數據量都是很是小的(範圍在byte和kilobyte之間)。咱們用術語znode代表咱們討論的是ZooKeeper的數據節點。

  znode維護了一個stat數據結構,它包含了如下信息:

  • czxid :這個znode建立時對應的zxid
  • mzxid :這個znode最後一次被修改對應的zxid
  • ctime :這個znode被建立的時間,單位是毫秒
  • mtime :這個znode最後一次被修改的時間,單位是毫秒
  • version :這個znode存儲的數據改動的次數,每次加1
  • cversion :這個znode的子節點改動的次數(建立或刪除),每次加1
  • aversion :這個znode的ACL權限的改動次數,每次加1
  • ephemeralOwner :若是這個znode是一個ephemeral 節點,存儲的是建立該節點的client的session id,不然默認爲0
  • dataLength :znode中存儲的數據的長度
  • numChildren: znode節點的子節點數目

  

  當這個節點的內容或是子節點有改動時,對應的Stat中存儲的值會被更新. ZooKeeper的客戶端獲取該znode的數據時,它也同時會得到這些stat信息。

  每一個命名空間對應的znode節點存儲的數據的讀和寫都是原子操做,也即讀的話會獲取當前存儲的全部數據,寫的話會用新數據覆蓋舊數據。每一個znode都有一個ACL(Access Control List)來限制誰能夠對該znode作哪些操做。

  ephemeral znode是ZooKeeper中的一個重要概念,這是一中特殊的znode,只要建立它的那個session一直存在,這個znode就一直存在,一旦這個session結束了,這個znode就會被刪除。這對於分佈式系統各個組件之間相互協做是很是有用的,能夠經過註冊ephemeral 節點來標識當前各個組件的運行狀態(live or dead)。

  

  ZooKeeper中存在下述的3種類型znode:

  • Persistent Nodes: 永久有效地節點,除非client顯式的刪除,不然一直存在
  • Ephemeral Nodes: 臨時節點,僅在建立該節點client保持鏈接期間有效,一旦鏈接丟失,zookeeper會自動刪除該節點
  • Sequence Nodes: 順序節點,client申請建立該節點時,zk會自動在節點路徑末尾添加遞增序號,這種類型是實現分佈式鎖,分佈式queue等特殊功能的關鍵

四. ZooKeeper的Watch

    ZooKeeper中有Watch的概念, Zookeeper Watch 定義以下:

「A watch event is one-time trigger, sent to the client that set the watch, which occurs when the data for which the watch was set changes.」

  Watch是由ZooKeeper的client在進行操做時設置的,全部的讀操做(getData(), getChildren(), and exists())均可以選擇設置watch。在我看來,watch能夠理解爲一個分佈式的回調,當client關心的znode發生變化時,zookeeper將會把消息傳回到client,並致使client的消息處理函數獲得調用. 後面咱們會詳細介紹ZooKeeper的Watch的實現機制。

 

五. ZooKeeper的保證

  ZooKeeper很是快而且很是簡單,因爲它的目標是成爲構建複雜系統的基石(好比說同步系統),它提供了一系列的保證,它們是:

1. 順序的一致性。 一個Client所發送的全部更新的執行順序跟它們的發送順序是一致的。

2. 原子性。更新操做要麼成功要麼失敗,不存在部分紅功的狀況。

3. 單一系統鏡像。在一個ZooKeeper集羣中,一個Client不論連接到哪一個Server上,它看到的ZooKeeper系統的狀態/視圖應該是相同的。

4. 可靠性。 一旦一個更新操做執行成功,這個更改就會一直存在直到有一個client又對它進行了更改/覆蓋。

5. 時效性。在必定的時間限制範圍內,確保全部client看到的ZooKeeper系統的數據是最新的。

 

  但願看完這一章以後,你們會對ZooKeeper有一個基礎的印象,後面的章節會詳細介紹ZooKeeper中設計和實現。

相關文章
相關標籤/搜索