原文位址
</h2>
zookeeper 是一個分布式的,開源的協調服務架構,服務于分布式應用程式。
它暴露了一系列的基礎的操作服務,是以分布式應用能夠基于這些服務,建構出更進階别的服務,比如同步,配置管理,分組和命名服務。
zookeeper設計上易于編碼,資料模型建構在我們熟悉的樹形結構目錄風格的檔案系統中。
zookeeper運作在java中,同時支援java和c 語言。正确的實作協調服務是公認的難幹的差事。 他們及其容易出錯,比如資源競争和死鎖.
zookeeper 的使命和力量來源于,将分布式應用從處理協調服務的泥潭中走出來。
</h3>
zookeeper是非常簡單的. zookeeper允許 分布式進行通過一個共享的樹形命名空間進行互相協調,這一命名空間跟檔案系統的組織方式類似.
zookeeper命名空間由資料寄存器組成,zookeeper中,我們稱他為,znodes, 這跟檔案和目錄非常類似..
不像一個典型的檔案系統,其設計時就是為了存儲資料.而zookeeper 資料是儲存在記憶體中的,這也就意味着zookeeper能實作一個高吞吐量和低延遲.(因為記憶體操作效率高)
zookeeper實作 對高性能,高可用性,嚴格的順序通路分外關注,. zookeeper性能比較優異也就意味着它可以使用在大的分布式系統中.
可靠性方面讓我們遠離了單點故障. 嚴格的順序通路意味着複雜的同步原語可以在用戶端實作.
zookeeper是有副本的, 就像分布式的處理協調服務一樣,zookeeper 本身就打算在伺服器叢集中使用副本機制,我們稱之為全體.

組成zookeeper 服務的所有機器節點互相之間都必須感覺到對方. 他們維護着目前機器狀态的記憶體快照,有事務日志和持久化存儲的快照.
隻要大多數的機器是可用的那麼整個zookeeper服務就是可用的.
用戶端連接配接到其中一台zookeeper伺服器,用戶端和zookeeper伺服器保持一個tcp連接配接,通過tcp連接配接發送請求獲得響應,
擷取事件監聽,發送心跳等等. 如果tcp連接配接被中斷了,用戶端會連接配接到另外一台zookeeper伺服器.
zookeeper是有序的, zookeeper給每一次更新操作都賦予一個編号,他這個編号反應了對zookeeper的事務性修改順序.
随後的操作能夠使用這一順序去實作更進階别的抽象,比如同步原語.
zookeeper是非常快的,尤其是針對 讀占據主要地位的應用負載的應用. zookeeper應用 運作在成千上萬的機器中,
當讀寫比例為10:1 情況下,zookeeper的性能是最優的.
zookeeper提供的命名空間非常想我們标準的檔案系統. 命名就是一系列用/分割的路徑元素. 每一個zookeeper節點的命名空間都是用路徑
進行辨別的.
不像标準的檔案系統,zookeeper 命名空間中的每個節點能夠有資料關聯,也有子節點.
就好比是檔案系統中一個檔案對象即可以是一個檔案也可以是一個檔案夾.(zookeeper被設計用來存儲協調資料:
狀态資訊,配置資訊,位置資訊等等, 是以資料存儲在每個節點中通常非常小,從幾個位元組到幾千位元組之間),
我們使用znode這個術語來使得我們讨論zookeeper資料節點相關内容時語義更加清晰明确.
znode管理着包含這一個狀态結構資料,它包含資料修改的版本号,acl修改及時間戳, 允許緩存校驗和協調更新.
znode資料每修改一次,版本号加一. 舉個實際的例子,每次用戶端收到資料的同時,也收到目前資料的版本号.
每一個節點都有一個acl通路控制清單,嚴格控制着誰能進行操作.
zookeeper 也有會話級别的節點的語義支援,這些znode節點随着會話的建立而激活,會話的結束的時候節點被删除.
會話級别的節點在實作實作例子的時候非常有用.
zookeeper支援監聽, 用戶端能夠設定監聽znode節點. 當znode節點變更時可能觸發或者移除監聽.當監聽事件被觸發了,
用戶端将會收到資料通知包,告訴用戶端節點資料被修改了. 同時如果目前用戶端和zookeeper節點的連接配接被斷開了.
用戶端将收到一個本地通知. 這些特性都能用在 具體例子中
zookeeper 簡單而性能優異. 由于他簡單快速的目标,他成為建構許多更加複雜服務的基礎,比如同步服務,他提供了一系列的保證.
1 順序一緻性: 來自用戶端的更新操作将會按照順序被作用.
2 原子性操作: 更新要麼全部成功,要麼全部失敗,沒有部分的結果.
3 統一的系統鏡像 無論用戶端連結的是哪台伺服器,都能獲得同樣的服務視圖,也就是說他是無狀态的.
4 可靠性保證 一旦寫入操作被執行(作用到伺服器),這個狀态将會被持久化,直到其他用戶端的修改生效.
5 時間線特性 用戶端通路伺服器系統鏡像能在一個特定時間通路内保證目前系統是實時更新的
zookeeper的設計原則之一就是提供簡單的程式設計接口. 是以,他僅僅提供了以下幾個操作.
1 建立 在目錄結構樹的某個位置建立一個節點
2 删除 删除某個節點
3 判斷是否存在 判斷某個位置上是否存在指定節點
4 擷取資料 從節點中擷取資料
5 設定/寫入資料 寫入資料到某個節點中
6 同步 等待寫入資料傳播到其他節點
想要進一步深入的探讨這些特性和操作,以及他們是如何實作更進階别的操作,請參看使用示例的相關内容
zookeeper元件構成圖中 展示了zookeeper服務中比較進階的元件服務.
除了請求處理器的異常情況之外. 組成zookeeper服務的每一台zookeeper伺服器 儲存着每個元件自身備份的副本.
副本資料庫是一個記憶體資料庫,儲存着整個目錄結構樹的資料.
所有的更新操作都記錄在磁盤日志當中,用于異常情況的恢複. 在更新作用到記憶體資料中之前,所有的寫入操作都是串行的,
這就保證了資料的強一緻性。
每個zookeeper伺服器節點服務若幹個用戶端. 用戶端連接配接到某一個指定的伺服器節點(随機配置設定算法配置設定的吧)和zookeeper進行互動.
讀請求都是由每個zookeeper伺服器記憶體資料庫的本地副本進行服務的(可以提高讀的性能,
這也就是為什麼zookeeper在讀寫比例為10:1的情況下,性能最佳的原因)
涉及到修改伺服器狀态和資料的寫入操作,需要通過一緻性協定進行處理.
一緻性協定中規定: 所有的寫入操作都是有選舉出來的唯一機器即我們稱之為leader(主節點) 的節點進行操作.
剩下的zookeeper機器,稱之為從節點(跟随者),接收來自leader節點的建議 并同意傳輸過來的消息.
也就是說對消息隻有服從和傳輸的特性. 消息層 關注的是當leader節點挂掉之後怎麼去替換他,并同步leader節點和follower節點之間的資料.
zookeeper 使用用戶端端原子消息協定.因為消息層是原子的,zookeeper 能保證本地副本和伺服器版本相同步.
當leader節點接收到寫入請求時, leader節點會計算下 目前系統的狀态是什麼,什麼時候講寫入作用到伺服器,
并把目前寫入操作轉換成一個事務并記錄下新的狀态.
zookeeper的程式設計接口 設計的非常簡單,但是用這些能實作一些其他更進階别的操作,比如同步原語,對成員進行分組和選舉等等.
一些分布式的應用用這些接口實作一些其他比較進階的功能
zookeeper 被設計的号稱高性能架構,但是事實情況如何呢?
來自雅虎的zookeeper開發團隊的研究證明了這點.
(可以檢視下zookeeper 吞吐量随着讀寫比例變化的圖表,即上圖)
在讀占主要比例的應用中,性能尤佳,因為寫操作涉及到伺服器之間狀态的同步.尤其是在協調服務這個典型案例中表現的尤其突出.
zookeeper 吞吐量和讀寫比例的變化關系用的是zookeeper3.2版本,運作在 雙核 2ghz 及sata 15k rpm 處理器配置的伺服器中.
其中一個負責zookeeper 日志裝置. 快照資訊寫入作業系統驅動中.
寫入請求是1kb寫入, 讀請求也是1kb的寫入(讀寫單元都是1kb).
servers 标示着 整個zookeeper的叢集大小, 即組成zookeeper服務的伺服器數.
整個zookeeper叢集有個限定,用戶端都不能直接連接配接zookeeper的leader 節點.
為了展示下,我們系統随着時間的推移及錯誤出現,我們運作了一個一個由7個機器組成的zookeeper服務中,我們使用和此前一樣飽和度的基準測試,
但是這次我們設定寫入操作的比例為30%, 這個比例是對我們預期的負載的保守估計值.
這個圖中有幾個比較關鍵的觀測點.首先,如果從節點失敗并快速恢複了,即使從節點失敗了,zookeeper仍然能夠承受住一個比較高的吞吐量.
但是,更為重要的一點事,leader節點的選舉算法 能讓系統快速恢複,防止吞吐量在短時間内迅速降低.觀察發現, zookeeper能在200毫秒内選舉出新的leader節點,
第三,随着從節點的恢複,zookeeper的吞吐量能快速提升,一旦恢複的從節點開始處理請求.
zookeeper 已經在許多企業級應用中獲得成功,雅虎内部使用zookeeper 進行協調和失敗恢複服務,及消息中間人服務
消息中間人是一個 高可擴充性的 基于釋出-訂閱的消息系統,
他管理成千上萬個消息主題,可以實作副本和資料傳輸的功能.
zookeeper在雅虎内部還用于資料抓取服務,即網絡爬蟲,同時緻力于失敗恢複.
許多雅虎的廣告系統使用zookeeper 實作高可靠服務.
我們歡迎并鼓勵所有使用者和開發者加入我們這個社群,發揮大家的專長。
詳情請關注apache中的zookeeper項目。