Zookeeper學習記錄(一):設計與實現

概述

  Zookeeper是一個分佈式的、開源的分佈式應用協調服務。它暴露了一組簡單的基礎原件,分佈式應用可以在這些原件之上實現更高級別的服務,如同步、配置維護、羣組、和命名。它被設計成容易編程實現的,並且使用一個常見的文件系統的樹型結構的數據模型。它運行在Java中,並且綁定了Java和C。

設計目的

  • 簡單:Zookeeper允許程序通過一個共享的類似於標準文件系統的有組織的分層命名空間分佈式處理協調。命名空間包括:數據寄存器 - 在Zookeeper中叫znodes, 它和文件、目錄一樣。和一般文件系統的不同之處是,它的設計就是爲了存儲,Zookeeper的數據保持在內存中,這就意味着它可以實現高吞吐量和低延遲的數據。

      Zookeeper的實現提供了一個優質的高性能、高可用,嚴格的訪問順序。Zookeeper的性能方面意味着它可以用於大型的分佈式系統。可靠性方面防止它成爲一個單         點故障。嚴格的順序意味着可以在客戶端實現複雜的同步原件。

  • 複製:像分佈式處理一樣,Zookeeper自己在處理協調的時候要複製多個主機,Zookeeper服務的組成部分必須彼此都知道彼此,它們維持了一個內存狀態影像,連同事務日誌和快照在一個持久化的存儲中。 只要大多數的服務器是可用的,Zookeeper服務就是可用的。客戶端連接到一個單獨的服務。客戶端保持了一個TCP連接,通過這個TCP連接發送請求、獲取響應、獲取watch事件、和發送心跳。如果這個連接斷了,會自動連接到其他不同的服務器。

 

 

 

 

 

 

  • 序列:Zookeeper用數字標記每一個更新,用它來反射出所有的事務順序。隨後的操作可以使用這個順序去實現更高級的抽象,例如同步原件。
  • 快速:它在"Read-dominant"工作負載中特別快。Zookeeper 應用運行在數以千計的機器上,並且它通常在讀比寫多的時候運行的最好,讀寫大概比例在10:1。

數據模型和分層的命名空間

  Zookeeper提供的命名空間非常像一個標準的文件系統。一個名字是一系列的以'/'隔開的一個路徑元素。Zookeeper命名空間中所有的節點都是通過路徑識別。

 

 

 

 

 

 

 

 

 

節點和臨時節點

  不像標準的文件系統,Zookeeper命名空間中的每個節點可以有數據也可以有子目錄。它就像一個既可以是文件也可以是目錄的文件系統。(Zookeeper被設計成保存協調數據:狀態信息,配置,位置信息,等等,所以每個節點存儲的數據通常較小,通常在1個字節到數千字節的範圍之內)我們使用術語znode來表明Zookeeper的數據節點。

  znode維持了一個stat結構,它包括數據變化的版本號、訪問控制列表變化、和時間戳,允許緩存驗證和協調更新。每當znode的數據有變化,版本號就會增加。例如,每當客戶端檢索數據時同時它也獲取數據的版本信息。

  命名空間中每個znode存儲的數據自動的讀取和寫入的,讀取時獲得znode所有關聯的數據字節,寫入時替換所有的數據。每個節點都有一個訪問控制列表來制約誰可以做什麼。

  Zookeeper還有一個臨時節點的概念。這些znode和session存活的一樣長,session創建時存活,當session結束,也跟着刪除。

條件的更新和watches

  Zookeeper支持watches的概念。客戶端可以在znode上設置一個watch。當znode發生變化時觸發並移除watch。當watch被觸發時,客戶端會接收到一個包說明znode有變化了。並且如果客戶端和其中一臺server中間的連接壞掉了,客戶端就會收到一個本地通知。這些可以用來[tbd]。

保證

  Zookeeper是非常簡單和高效的。因爲它的目標就是,作爲建設複雜服務的基礎,比如同步。zookeeper提供了一套保證,他們包括:

  • 順序一致性 - 來自客戶端的更新會按順序應用。
  • 原子性 - 更新成功或者失敗,沒有局部的結果產生。
  • 唯一系統映像 - 一個客戶端不管連接到哪個服務端都會看到同樣的視圖。
  • 可靠性- 一旦一個更新被應用,它將從更新的時間開始一直保持到一個客戶端重寫更新。
  • 時效性 - 系統中的客戶端視圖在特定的時間點保證成爲是最新的。

簡單API

  Zookeeper的設計目標的其中之一就是提供一個簡單的程序接口。因此,它只支持這些操作:

  • create - 在樹形結構的位置中創建節點
  • delete - 刪除一個節點
  • exists - 測試節點在指定位置上是否存在
  • get data - 從節點上讀取數據
  • set data - 往節點寫入輸入
  • get chilren - 檢索一個節點的子節點列表
  • sync - 等待傳輸數據

實現

  Zookeeper Compnents 展示了Zookeeper服務的高級組件。除了請求處理器的異常之外,組成Zookeeper服務的服務器都會複製它們自己組件的副本。

 

 

 

 

 

 

 

 

  Replicated database 是一個內存數據庫,它包含全部的數據樹。爲了可恢復性,更新記錄保存到磁盤上,並且寫入操作在應用到內存數據庫之前被序列化到磁盤上。
每個Zookeeper 服務端服務客戶端。客戶端正確的連接到一個服務器提交請求。每個服務端數據庫的本地副本爲讀請求提供服務。服務的變化狀態請求、寫請求,被一個協議保護。
  作爲協議的一部分,所有的寫操作從客戶端轉遞到一臺單獨服務器,稱爲leader。其他的Zookeeper服務器叫做follows,它接收來自leader的消息建議並達成一致的消息建議。消息管理層負責在失敗的時候更換Leader並同步Follows。
  Zookeeper使用了一個自定義的原子消息協議。因爲消息層是原子的,Zookeeper可以保證本地副本從不出現偏差。當leader接受到一個寫請求,它計算寫操作被應用時系統的狀態,並將捕獲到的新狀態轉化進入事務。

使用

程序接口實現Zookeeper非常簡單。然而,用它你可以實現更高級的操作,如同步基本數據,組成員,所有權,等等。

性能

Zookeeper被設計成高性能的。但真的是這樣嗎?Yahoo的Zookeeper開發團隊的結果表明了它就是這樣的。它在應用中讀比寫多的時候有特別高的性能,因爲在寫的時候包含所有服務器狀態同步。(讀比寫多是協調服務的典型案例)

 

 

 

 

 

 

 

 

 

 

 

 

  上圖是Zookeeper3.2版本在dual 2Ghz Xeon and two SATA 15K RPM 驅動配置的服務器上的吞吐量圖像。一個驅動作爲專門的Zookeeper日誌裝置。快照寫進操作系統驅動。1k的寫請求和1K的讀取請求。"Servers" 表明了Zookeeper全體的大小,組成Zookeeper服務的服務器數量。接近於30臺機器模仿客戶端。Zookeeper全體被配置爲leaders不允許客戶端連接。

注意:相對於3.1的發佈版本,在3.2的版本中讀寫性能都改善了。

  測試基準也表明它是可靠的。Reliability in the Presence of Errors 展示了怎樣部署應對各種失敗。事件標記出以下幾點:

  1. 一個follower的故障和恢復
  2. 不同的follower的故障和恢復
  3. leader的故障
  4. 兩個followers的故障和恢復
  5. 另一個leader的故障

可靠性

  展示我們啓動了7臺機器組成的Zookeeper服務注入超時故障的行爲。我們之前運行了相同的飽和基準,但現在我們保持寫的百分比在不變的30%,這是一個比較保守的工作負載比。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  從這張圖有幾個重要的觀察。第一,如果follows失敗並快速的恢復,Zookeeper能夠維持一個高的吞吐量儘管有故障。但也許更重要的是,leader選舉算法允許系統快速恢復,足以預防吞吐量大幅下降。在我們的觀測中,Zookeeper用了不到200ms的時間就選出了一個新的leader。第三,隨着follower恢復,Zookeeper一旦開始處理它們的請求,它能夠再次提高吞吐量。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章