ZooKeeper典型應(yīng)用場景一覽(轉(zhuǎn))

ZooKeeper是一個高可用的分布式數(shù)據(jù)管理與系統(tǒng)協(xié)調(diào)框架贞盯。基于對Paxos算法的實現(xiàn)希痴,使該框架保證了分布式環(huán)境中數(shù)據(jù)的強一致性,也正是基于這樣的特性春感,使得ZooKeeper解決很多分布式問題砌创。網(wǎng)上對ZK的應(yīng)用場景也有不少介紹,本文將結(jié)合作者身邊的項目例子鲫懒,系統(tǒng)地對ZK的應(yīng)用場景進行一個分門歸類的介紹嫩实。
值得注意的是,ZK并非天生就是為這些應(yīng)用場景設(shè)計的窥岩,都是后來眾多開發(fā)者根據(jù)其框架的特性甲献,利用其提供的一系列API接口(或者稱為原語集),摸索出來的典型使用方法谦秧。因此竟纳,也非常歡迎讀者分享你在ZK使用上的奇技淫巧撵溃。

數(shù)據(jù)發(fā)布與訂閱(配置中心)

發(fā)布與訂閱模型,即所謂的配置中心锥累,顧名思義就是發(fā)布者將數(shù)據(jù)發(fā)布到ZK節(jié)點上缘挑,供訂閱者動態(tài)獲取數(shù)據(jù),實現(xiàn)配置信息的集中式管理和動態(tài)更新桶略。例如全局的配置信息语淘,服務(wù)式服務(wù)框架的服務(wù)地址列表等就非常適合使用。

  1. 應(yīng)用中用到的一些配置信息放到ZK上進行集中管理际歼。這類場景通常是這樣:應(yīng)用在啟動的時候會主動來獲取一次配置惶翻,同時,在節(jié)點上注冊一個Watcher鹅心,這樣一來吕粗,以后每次配置有更新的時候,都會實時通知到訂閱的客戶端旭愧,從來達到獲取最新配置信息的目的颅筋。
  2. 分布式搜索服務(wù)中,索引的元信息和服務(wù)器集群機器的節(jié)點狀態(tài)存放在ZK的一些指定節(jié)點输枯,供各個客戶端訂閱使用议泵。
  3. 分布式日志收集系統(tǒng)。這個系統(tǒng)的核心工作是收集分布在不同機器的日志桃熄。收集器通常是按照應(yīng)用來分配收集任務(wù)單元先口,因此需要在ZK上創(chuàng)建一個以應(yīng)用名作為path的節(jié)點P,并將這個應(yīng)用的所有機器ip瞳收,以子節(jié)點的形式注冊到節(jié)點P上碉京,這樣一來就能夠?qū)崿F(xiàn)機器變動的時候,能夠?qū)崟r通知到收集器調(diào)整任務(wù)分配螟深。
  4. 系統(tǒng)中有些信息需要動態(tài)獲取收夸,并且還會存在人工手動去修改這個信息的發(fā)問。通常是暴露出接口血崭,例如JMX接口,來獲取一些運行時的信息厘灼。引入ZK之后夹纫,就不用自己實現(xiàn)一套方案了,只要將這些信息存放到指定的ZK節(jié)點上即可设凹。
    注意:在上面提到的應(yīng)用場景中舰讹,有個默認前提是:數(shù)據(jù)量很小,但是數(shù)據(jù)更新可能會比較快的場景闪朱。

負載均衡

這里說的負載均衡是指軟負載均衡月匣。在分布式環(huán)境中钻洒,為了保證高可用性,通常同一個應(yīng)用或同一個服務(wù)的提供方都會部署多份锄开,達到對等服務(wù)素标。而消費者就須要在這些對等的服務(wù)器中選擇一個來執(zhí)行相關(guān)的業(yè)務(wù)邏輯,其中比較典型的是消息中間件中的生產(chǎn)者萍悴,消費者負載均衡头遭。
消息中間件中發(fā)布者和訂閱者的負載均衡,linkedin開源的KafkaMQ和阿里開源的metaq都是通過zookeeper來做到生產(chǎn)者癣诱、消費者的負載均衡计维。這里以metaq為例如講下:

生產(chǎn)者負載均衡

metaq發(fā)送消息的時候,生產(chǎn)者在發(fā)送消息的時候必須選擇一臺broker上的一個分區(qū)來發(fā)送消息撕予,因此metaq在運行過程中鲫惶,會把所有broker和對應(yīng)的分區(qū)信息全部注冊到ZK指定節(jié)點上,默認的策略是一個依次輪詢的過程实抡,生產(chǎn)者在通過ZK獲取分區(qū)列表之后欠母,會按照brokerId和partition的順序排列組織成一個有序的分區(qū)列表,發(fā)送的時候按照從頭到尾循環(huán)往復(fù)的方式選擇一個分區(qū)來發(fā)送消息澜术。

消費負載均衡

在消費過程中艺蝴,一個消費者會消費一個或多個分區(qū)中的消息,但是一個分區(qū)只會由一個消費者來消費鸟废。MetaQ的消費策略是:

  1. 每個分區(qū)針對同一個group只掛載一個消費者猜敢。
  2. 如果同一個group的消費者數(shù)目大于分區(qū)數(shù)目,則多出來的消費者將不參與消費盒延。
  3. 如果同一個group的消費者數(shù)目小于分區(qū)數(shù)目缩擂,則有部分消費者需要額外承擔(dān)消費任務(wù)。
    在某個消費者故障或者重啟等情況下添寺,其他消費者會感知到這一變化(通過 zookeeper watch消費者列表)胯盯,然后重新進行負載均衡,保證所有的分區(qū)都有消費者進行消費计露。

命名服務(wù)(Naming Service)

命名服務(wù)也是分布式系統(tǒng)中比較常見的一類場景博脑。在分布式系統(tǒng)中,通過使用命名服務(wù)票罐,客戶端應(yīng)用能夠根據(jù)指定名字來獲取資源或服務(wù)的地址叉趣,提供者等信息。被命名的實體通掣醚海可以是集群中的機器疗杉,提供的服務(wù)地址,遠程對象等等——這些我們都可以統(tǒng)稱他們?yōu)槊郑∟ame)蚕礼。其中較為常見的就是一些分布式服務(wù)框架中的服務(wù)地址列表烟具。通過調(diào)用ZK提供的創(chuàng)建節(jié)點的API梢什,能夠很容易創(chuàng)建一個全局唯一的path,這個path就可以作為一個名稱朝聋。

阿里巴巴集團開源的分布式服務(wù)框架Dubbo中使用ZooKeeper來作為其命名服務(wù)嗡午,維護全局的服務(wù)地址列表,點擊這里查看Dubbo開源項目玖翅。在Dubbo實現(xiàn)中:
服務(wù)提供者在啟動的時候翼馆,向ZK上的指定節(jié)點/dubbo/${serviceName}/providers目錄下寫入自己的URL地址,這個操作就完成了服務(wù)的發(fā)布金度。

服務(wù)消費者啟動的時候应媚,訂閱/dubbo/${serviceName}/providers目錄下的提供者URL地址, 并向/dubbo/${serviceName} /consumers目錄下寫入自己的URL地址猜极。
注意中姜,所有向ZK上注冊的地址都是臨時節(jié)點,這樣就能夠保證服務(wù)提供者和消費者能夠自動感應(yīng)資源的變化跟伏。

另外丢胚,Dubbo還有針對服務(wù)粒度的監(jiān)控,方法是訂閱/dubbo/${serviceName}目錄下所有提供者和消費者的信息受扳。

分布式通知/協(xié)調(diào)

ZooKeeper中特有watcher注冊與異步通知機制携龟,能夠很好的實現(xiàn)分布式環(huán)境下不同系統(tǒng)之間的通知與協(xié)調(diào),實現(xiàn)對數(shù)據(jù)變更的實時處理勘高。使用方法通常是不同系統(tǒng)都對ZK上同一個znode進行注冊峡蟋,監(jiān)聽znode的變化(包括znode本身內(nèi)容及子節(jié)點的),其中一個系統(tǒng)update了znode华望,那么另一個系統(tǒng)能夠收到通知蕊蝗,并作出相應(yīng)處理

  1. 另一種心跳檢測機制:檢測系統(tǒng)和被檢測系統(tǒng)之間并不直接關(guān)聯(lián)起來,而是通過zk上某個節(jié)點關(guān)聯(lián)赖舟,大大減少系統(tǒng)耦合蓬戚。

  2. 另一種系統(tǒng)調(diào)度模式:某系統(tǒng)有控制臺和推送系統(tǒng)兩部分組成,控制臺的職責(zé)是控制推送系統(tǒng)進行相應(yīng)的推送工作宾抓。管理人員在控制臺作的一些操作子漩,實際上是修改了ZK上某些節(jié)點的狀態(tài),而ZK就把這些變化通知給他們注冊Watcher的客戶端石洗,即推送系統(tǒng)痛单,于是,作出相應(yīng)的推送任務(wù)劲腿。

  3. 另一種工作匯報模式:一些類似于任務(wù)分發(fā)系統(tǒng),子任務(wù)啟動后鸟妙,到zk來注冊一個臨時節(jié)點焦人,并且定時將自己的進度進行匯報(將進度寫回這個臨時節(jié)點)挥吵,這樣任務(wù)管理者就能夠?qū)崟r知道任務(wù)進度。
    總之花椭,使用zookeeper來進行分布式通知和協(xié)調(diào)能夠大大降低系統(tǒng)之間的耦合

集群管理與Master選舉

集群機器監(jiān)控:這通常用于那種對集群中機器狀態(tài)忽匈,機器在線率有較高要求的場景,能夠快速對集群中機器變化作出響應(yīng)矿辽。這樣的場景中丹允,往往有一個監(jiān)控系統(tǒng),實時檢測集群機器是否存活袋倔。過去的做法通常是:監(jiān)控系統(tǒng)通過某種手段(比如ping)定時檢測每個機器雕蔽,或者每個機器自己定時向監(jiān)控系統(tǒng)匯報“我還活著”。 這種做法可行宾娜,但是存在兩個比較明顯的問題:

  1. 集群中機器有變動的時候批狐,牽連修改的東西比較多。
  2. 有一定的延時前塔。

利用ZooKeeper有兩個特性孤钦,就可以實現(xiàn)另一種集群機器存活性監(jiān)控系統(tǒng):

  1. 客戶端在節(jié)點 x 上注冊一個Watcher诡必,那么如果 x?的子節(jié)點變化了,會通知該客戶端。
  2. 創(chuàng)建EPHEMERAL類型的節(jié)點捐康,一旦客戶端和服務(wù)器的會話結(jié)束或過期,那么該節(jié)點就會消失词顾。
    例如蠕趁,監(jiān)控系統(tǒng)在 /clusterServers 節(jié)點上注冊一個Watcher,以后每動態(tài)加機器凑保,那么就往 /clusterServers 下創(chuàng)建一個 EPHEMERAL類型的節(jié)點:/clusterServers/{hostname}. 這樣冈爹,監(jiān)控系統(tǒng)就能夠?qū)崟r知道機器的增減情況,至于后續(xù)處理就是監(jiān)控系統(tǒng)的業(yè)務(wù)了欧引。
  3. Master選舉則是zookeeper中最為經(jīng)典的應(yīng)用場景了频伤。
    在分布式環(huán)境中,相同的業(yè)務(wù)應(yīng)用分布在不同的機器上芝此,有些業(yè)務(wù)邏輯(例如一些耗時的計算憋肖,網(wǎng)絡(luò)I/O處理),往往只需要讓整個集群中的某一臺機器進行執(zhí)行婚苹,其余機器可以共享這個結(jié)果岸更,這樣可以大大減少重復(fù)勞動,提高性能膊升,于是這個master選舉便是這種場景下的碰到的主要問題怎炊。
    利用ZooKeeper的強一致性,能夠保證在分布式高并發(fā)情況下節(jié)點創(chuàng)建的全局唯一性,即:同時有多個客戶端請求創(chuàng)建 /currentMaster 節(jié)點评肆,最終一定只有一個客戶端請求能夠創(chuàng)建成功债查。利用這個特性,就能很輕易的在分布式環(huán)境中進行集群選取了瓜挽。
    另外盹廷,這種場景演化一下,就是動態(tài)Master選舉久橙。這就要用到EPHEMERAL_SEQUENTIAL類型節(jié)點的特性了俄占。
    上文中提到,所有客戶端創(chuàng)建請求淆衷,最終只有一個能夠創(chuàng)建成功缸榄。在這里稍微變化下,就是允許所有請求都能夠創(chuàng)建成功吭敢,但是得有個創(chuàng)建順序碰凶,于是所有的請求最終在ZK上創(chuàng)建結(jié)果的一種可能情況是這樣: /currentMaster/{sessionId}-1 ,/currentMaster/{sessionId}-2,/currentMaster/{sessionId}-3 ….. 每次選取序列號最小的那個機器作為Master,如果這個機器掛了鹿驼,由于他創(chuàng)建的節(jié)點會馬上小時欲低,那么之后最小的那個機器就是Master了。
  4. 在搜索系統(tǒng)中畜晰,如果集群中每個機器都生成一份全量索引砾莱,不僅耗時,而且不能保證彼此之間索引數(shù)據(jù)一致凄鼻。因此讓集群中的Master來進行全量索引的生成腊瑟,然后同步到集群中其它機器。另外块蚌,Master選舉的容災(zāi)措施是闰非,可以隨時進行手動指定master,就是說應(yīng)用在zk在無法獲取master信息時峭范,可以通過比如http方式财松,向一個地方獲取master。
  5. 在Hbase中纱控,也是使用ZooKeeper來實現(xiàn)動態(tài)HMaster的選舉辆毡。在Hbase實現(xiàn)中,會在ZK上存儲一些ROOT表的地址和HMaster的地址甜害,HRegionServer也會把自己以臨時節(jié)點(Ephemeral)的方式注冊到Zookeeper中舶掖,使得HMaster可以隨時感知到各個HRegionServer的存活狀態(tài),同時尔店,一旦HMaster出現(xiàn)問題眨攘,會重新選舉出一個HMaster來運行主慰,從而避免了HMaster的單點問題

分布式鎖

分布式鎖,這個主要得益于ZooKeeper為我們保證了數(shù)據(jù)的強一致性期犬。鎖服務(wù)可以分為兩類河哑,一個是保持獨占,另一個是控制時序龟虎。

  1. 所謂保持獨占,就是所有試圖來獲取這個鎖的客戶端沙庐,最終只有一個可以成功獲得這把鎖鲤妥。通常的做法是把zk上的一個znode看作是一把鎖,通過create znode的方式來實現(xiàn)拱雏。所有客戶端都去創(chuàng)建 /distribute_lock 節(jié)點棉安,最終成功創(chuàng)建的那個客戶端也即擁有了這把鎖。

  2. 控制時序铸抑,就是所有視圖來獲取這個鎖的客戶端贡耽,最終都是會被安排執(zhí)行,只是有個全局時序了鹊汛。做法和上面基本類似蒲赂,只是這里 /distribute_lock 已經(jīng)預(yù)先存在,客戶端在它下面創(chuàng)建臨時有序節(jié)點(這個可以通過節(jié)點的屬性控制:CreateMode.EPHEMERAL_SEQUENTIAL來指定)刁憋。Zk的父節(jié)點(/distribute_lock)維持一份sequence,保證子節(jié)點創(chuàng)建的時序性滥嘴,從而也形成了每個客戶端的全局時序。

分布式隊列

隊列方面至耻,簡單地講有兩種若皱,一種是常規(guī)的先進先出隊列,另一種是要等到隊列成員聚齊之后的才統(tǒng)一按序執(zhí)行尘颓。

對于第一種先進先出隊列走触,和分布式鎖服務(wù)中的控制時序場景基本原理一致,這里不再贅述疤苹。 第二種隊列其實是在FIFO隊列的基礎(chǔ)上作了一個增強互广。通常可以在 /queue 這個znode下預(yù)先建立一個/queue/num 節(jié)點痰催,并且賦值為n(或者直接給/queue賦值n)兜辞,表示隊列大小,之后每次有隊列成員加入后夸溶,就判斷下是否已經(jīng)到達隊列大小逸吵,決定是否可以開始執(zhí)行了。這種用法的典型場景是缝裁,分布式環(huán)境中扫皱,一個大任務(wù)Task A足绅,需要在很多子任務(wù)完成(或條件就緒)情況下才能進行。這個時候韩脑,凡是其中一個子任務(wù)完成(就緒)氢妈,那么就去 /taskList 下建立自己的臨時時序節(jié)點(CreateMode.EPHEMERAL_SEQUENTIAL),當 /taskList 發(fā)現(xiàn)自己下面的子節(jié)點滿足指定個數(shù)段多,就可以進行下一步按序進行處理了首量。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市进苍,隨后出現(xiàn)的幾起案子加缘,更是在濱河造成了極大的恐慌,老刑警劉巖觉啊,帶你破解...
    沈念sama閱讀 210,914評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件拣宏,死亡現(xiàn)場離奇詭異,居然都是意外死亡杠人,警方通過查閱死者的電腦和手機勋乾,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,935評論 2 383
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來嗡善,“玉大人辑莫,你說我怎么就攤上這事÷四危” “怎么了摆昧?”我有些...
    開封第一講書人閱讀 156,531評論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀的道長蜒程。 經(jīng)常有香客問我绅你,道長,這世上最難降的妖魔是什么昭躺? 我笑而不...
    開封第一講書人閱讀 56,309評論 1 282
  • 正文 為了忘掉前任忌锯,我火速辦了婚禮,結(jié)果婚禮上领炫,老公的妹妹穿的比我還像新娘偶垮。我一直安慰自己,他們只是感情好帝洪,可當我...
    茶點故事閱讀 65,381評論 5 384
  • 文/花漫 我一把揭開白布似舵。 她就那樣靜靜地躺著,像睡著了一般葱峡。 火紅的嫁衣襯著肌膚如雪砚哗。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,730評論 1 289
  • 那天砰奕,我揣著相機與錄音蛛芥,去河邊找鬼提鸟。 笑死,一個胖子當著我的面吹牛仅淑,可吹牛的內(nèi)容都是我干的称勋。 我是一名探鬼主播,決...
    沈念sama閱讀 38,882評論 3 404
  • 文/蒼蘭香墨 我猛地睜開眼涯竟,長吁一口氣:“原來是場噩夢啊……” “哼赡鲜!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起庐船,我...
    開封第一講書人閱讀 37,643評論 0 266
  • 序言:老撾萬榮一對情侶失蹤蝗蛙,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后醉鳖,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,095評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡哮内,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,448評論 2 325
  • 正文 我和宋清朗相戀三年盗棵,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片北发。...
    茶點故事閱讀 38,566評論 1 339
  • 序言:一個原本活蹦亂跳的男人離奇死亡纹因,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出琳拨,到底是詐尸還是另有隱情瞭恰,我是刑警寧澤,帶...
    沈念sama閱讀 34,253評論 4 328
  • 正文 年R本政府宣布狱庇,位于F島的核電站惊畏,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏密任。R本人自食惡果不足惜颜启,卻給世界環(huán)境...
    茶點故事閱讀 39,829評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望浪讳。 院中可真熱鬧缰盏,春花似錦、人聲如沸淹遵。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,715評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽透揣。三九已至济炎,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間淌实,已是汗流浹背冻辩。 一陣腳步聲響...
    開封第一講書人閱讀 31,945評論 1 264
  • 我被黑心中介騙來泰國打工猖腕, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人恨闪。 一個月前我還...
    沈念sama閱讀 46,248評論 2 360
  • 正文 我出身青樓倘感,卻偏偏與公主長得像,于是被迫代替她去往敵國和親咙咽。 傳聞我的和親對象是個殘疾皇子老玛,可洞房花燭夜當晚...
    茶點故事閱讀 43,440評論 2 348

推薦閱讀更多精彩內(nèi)容