zookeeper經常使用使用場景

ZooKeeper是一個高可用的分佈式數據管理與系統協調框架。基於對Paxos算法的實現,使該框架保證了分佈式環境中數據的強一致性,也正是基於這樣的特性,使得zookeeper可以應用於不少場景。網上對zk的使用場景也有很多介紹,本文將結合做者身邊的項目例子,系統的對zk的使用場景進行歸類介紹。 值得注意的是,zk並非生來就爲這些場景設計,都是後來衆多開發者根據框架的特性,摸索出來的典型使用方法。所以,也很是歡迎你分享你在ZK使用上的奇技淫巧。node

場景類別 典型場景描述(ZK特性,使用方法) 應用中的具體使用
數據發佈與訂閱 發佈與訂閱即所謂的配置管理,顧名思義就是將數據發佈到zk節點上,供訂閱者動態獲取數據,實現配置信息的集中式管理和動態更新。例如全局的配置信息,地址列表等就很是適合使用。 1. 索引信息和集羣中機器節點狀態存放在zk的一些指定節點,供各個客戶端訂閱使用。2. 系統日誌(通過處理後的)存儲,這些日誌一般2-3天后被清除。

3. 應用中用到的一些配置信息集中管理,在應用啓動的時候主動來獲取一次,而且在節點上註冊一個Watcher,之後每次配置有更新,實時通知到應用,獲取最新配置信息。算法

4. 業務邏輯中須要用到的一些全局變量,好比一些消息中間件的消息隊列一般有個offset,這個offset存放在zk上,這樣集羣中每一個發送者都能知道當前的發送進度。api

5. 系統中有些信息須要動態獲取,而且還會存在人工手動去修改這個信息。之前一般是暴露出接口,例如JMX接口,有了zk後,只要將這些信息存放到zk節點上便可。服務器

Name Service 這個主要是做爲分佈式命名服務,經過調用zk的create node api,可以很容易建立一個全局惟一的path,這個path就能夠做爲一個名稱。
分佈通知/協調 ZooKeeper中特有watcher註冊與異步通知機制,可以很好的實現分佈式環境下不一樣系統之間的通知與協調,實現對數據變動的實時處理。使用方法一般是不一樣系統都對ZK上同一個znode進行註冊,監聽znode的變化(包括znode自己內容及子節點的),其中一個系統update了znode,那麼另外一個系統可以收到通知,並做出相應處理。 1. 另外一種心跳檢測機制:檢測系統和被檢測系統之間並不直接關聯起來,而是經過zk上某個節點關聯,大大減小系統耦合。2. 另外一種系統調度模式:某系統有控制檯和推送系統兩部分組成,控制檯的職責是控制推送系統進行相應的推送工做。管理人員在控制檯做的一些操做,其實是修改了ZK上某些節點的狀態,而zk就把這些變化通知給他們註冊Watcher的客戶端,即推送系統,因而,做出相應的推送任務。

3. 另外一種工做彙報模式:一些相似於任務分發系統,子任務啓動後,到zk來註冊一個臨時節點,而且定時將本身的進度進行彙報(將進度寫回這個臨時節點),這樣任務管理者就可以實時知道任務進度。網絡

總之,使用zookeeper來進行分佈式通知和協調可以大大下降系統之間的耦合。session

分佈式鎖 分佈式鎖,這個主要得益於ZooKeeper爲咱們保證了數據的強一致性,即用戶只要徹底相信每時每刻,zk集羣中任意節點(一個zk server)上的相同znode的數據是必定是相同的。鎖服務能夠分爲兩類,一個是保持獨佔,另外一個是控制時序。

所謂保持獨佔,就是全部試圖來獲取這個鎖的客戶端,最終只有一個能夠成功得到這把鎖。一般的作法是把zk上的一個znode看做是一把鎖,經過create znode的方式來實現。全部客戶端都去建立 /distribute_lock 節點,最終成功建立的那個客戶端也即擁有了這把鎖。併發

控制時序,就是全部視圖來獲取這個鎖的客戶端,最終都是會被安排執行,只是有個全局時序了。作法和上面基本相似,只是這裏 /distribute_lock 已經預先存在,客戶端在它下面建立臨時有序節點(這個能夠經過節點的屬性控制:CreateMode.EPHEMERAL_SEQUENTIAL來指定)。Zk的父節點(/distribute_lock)維持一份sequence,保證子節點建立的時序性,從而也造成了每一個客戶端的全局時序。框架


集羣管理 1. 集羣機器監控:這一般用於那種對集羣中機器狀態,機器在線率有較高要求的場景,可以快速對集羣中機器變化做出響應。這樣的場景中,每每有一個監控系統,實時檢測集羣機器是否存活。過去的作法一般是:監控系統經過某種手段(好比ping)定時檢測每一個機器,或者每一個機器本身定時向監控系統彙報「我還活着」。 這種作法可行,可是存在兩個比較明顯的問題:1. 集羣中機器有變更的時候,牽連修改的東西比較多。2. 有必定的延時。

利用ZooKeeper有兩個特性,就能夠實時另外一種集羣機器存活性監控系統:a. 客戶端在節點 x 上註冊一個Watcher,那麼若是 x 的子節點變化了,會通知該客戶端。b. 建立EPHEMERAL類型的節點,一旦客戶端和服務器的會話結束或過時,那麼該節點就會消失。異步

例如,監控系統在 /clusterServers 節點上註冊一個Watcher,之後每動態加機器,那麼就往 /clusterServers 下建立一個 EPHEMERAL類型的節點:/clusterServers/{hostname}. 這樣,監控系統就可以實時知道機器的增減狀況,至於後續處理就是監控系統的業務了。
2. Master選舉則是zookeeper中最爲經典的使用場景了。分佈式

在分佈式環境中,相同的業務應用分佈在不一樣的機器上,有些業務邏輯(例如一些耗時的計算,網絡I/O處理),每每只須要讓整個集羣中的某一臺機器進行執行,其他機器能夠共享這個結果,這樣能夠大大減小重複勞動,提升性能,因而這個master選舉即是這種場景下的碰到的主要問題。

利用ZooKeeper的強一致性,可以保證在分佈式高併發狀況下節點建立的全局惟一性,即:同時有多個客戶端請求建立 /currentMaster 節點,最終必定只有一個客戶端請求可以建立成功。

利用這個特性,就能很輕易的在分佈式環境中進行集羣選取了。

另外,這種場景演化一下,就是動態Master選舉。這就要用到 EPHEMERAL_SEQUENTIAL類型節點的特性了。

上文中提到,全部客戶端建立請求,最終只有一個可以建立成功。在這裏稍微變化下,就是容許全部請求都可以建立成功,可是得有個建立順序,因而全部的請求最終在ZK上建立結果的一種可能狀況是這樣: /currentMaster/{sessionId}-1 , /currentMaster/{sessionId}-2 , /currentMaster/{sessionId}-3 ….. 每次選取序列號最小的那個機器做爲Master,若是這個機器掛了,因爲他建立的節點會立刻小時,那麼以後最小的那個機器就是Master了。

1. 在搜索系統中,若是集羣中每一個機器都生成一份全量索引,不只耗時,並且不能保證彼此之間索引數據一致。所以讓集羣中的Master來進行全量索引的生成,而後同步到集羣中其它機器。2. 另外,Master選舉的容災措施是,能夠隨時進行手動指定master,就是說應用在zk在沒法獲取master信息時,能夠經過好比http方式,向一個地方獲取master。
分佈式隊列 隊列方面,我目前感受有兩種,一種是常規的先進先出隊列,另外一種是要等到隊列成員聚齊以後的才統一按序執行。對於第二種先進先出隊列,和分佈式鎖服務中的控制時序場景基本原理一致,這裏再也不贅述。

第二種隊列實際上是在FIFO隊列的基礎上做了一個加強。一般能夠在 /queue 這個znode下預先創建一個/queue/num 節點,而且賦值爲n(或者直接給/queue賦值n),表示隊列大小,以後每次有隊列成員加入後,就判斷下是否已經到達隊列大小,決定是否能夠開始執行了。這種用法的典型場景是,分佈式環境中,一個大任務Task A,須要在不少子任務完成(或條件就緒)狀況下才能進行。這個時候,凡是其中一個子任務完成(就緒),那麼就去 /taskList 下創建本身的臨時時序節點(CreateMode.EPHEMERAL_SEQUENTIAL),當 /taskList 發現本身下面的子節點知足指定個數,就能夠進行下一步按序進行處理了。

相關文章
相關標籤/搜索