深入理解ZooKeeper

?什么是ZooKeeper虱朵?ZooKeeper是一個分布式布持、開源的分布式應用協(xié)作服務豌拙。它提供了一組簡單的原語,分布式應用程序可以在這些原語的基礎上實現更高級別的服務题暖,用于同步按傅、配置維護、組命名,提供簡單易用的接口給用戶使用胧卤。
?本文將介紹ZooKeeper的基本概念唯绍、使用場景、ZAB協(xié)議和請求處理枝誊。

ZooKeeper的概念和基礎

1. 服務架構

image.png

?ZooKeeper本身是一個高可用的服務况芒,ZooKeeper集群中服務器有三種角色leader、follower叶撒、observer绝骚,leader提供讀和寫的服務耐版,follower只提供讀的服務和參與leader選舉,observer和follower的區(qū)別是observer不參與選舉压汪。

2. 數據結構

image.png

?ZooKeeper的數據結構類似于一個文件系統(tǒng)粪牲。存放一個個的數據節(jié)點(Znode),Znode的屬性有永久(persistent)止剖、臨時(ephemeral)和有序(sequential)腺阳。

  • 永久:創(chuàng)建成功之后將永久存在,只能通過調用delete來進行刪除滴须。
  • 臨時:當創(chuàng)建該節(jié)點的客戶端崩潰或關閉了與ZooKeeper的連接時舌狗,這個節(jié)點就會被刪除。
  • 有序:按照創(chuàng)建的時間順序節(jié)點會分配唯一個單調遞增的整數扔水。
    總之痛侍,znode一共有4種類型:永久的(persistent)、臨時的(ephemeral)魔市、永久有序的(persistent_sequential)和臨時有序的(ephemeral_sequential)主届。

3. 監(jiān)控與通知
?Watcher是Zookeeper中很重要的機制〈拢客戶端通過對znode創(chuàng)建watcher當節(jié)點發(fā)生變化的時候(節(jié)點刪除君丁、數據更改、子節(jié)點變化等)将宪,ZooKeeper將會通知注冊Watcher的客戶端節(jié)點已經變更绘闷。
?監(jiān)聽事件有推和拉的形式,所謂推就是事件觸發(fā)之后服務器向客戶端推送數據较坛,而拉就是客戶端輪詢服務器檢查事件是否觸發(fā)印蔗。而ZooKeeper采用推和拉結合的形式,事件觸發(fā)之后丑勤,服務器給客戶端推送事件(不包含事件的內容华嘹,只有發(fā)生了什么事件),客戶端收到通知之后去服務器拉去最新的數據法竞,采用這種方式每次每次通知只需要傳輸少量數據就行了耙厚,減少I/O壓力。需要注意的是ZooKeeper在事件通知之后會將Watcher給刪除岔霸,為了繼續(xù)監(jiān)聽薛躬,客戶端必須在每次通知后設置一個新的Watcher。

4. 會話(Session)
?在對ZooKeeper集合執(zhí)行任何請求前呆细,一個客戶端必須先與服務建立會話泛豪∈薨#客戶端與服務器將會建立一個TCP的長連接放妈,第一次建立連接的時候也是Session開始的時候册赛,客戶端與服務器通過這個連接發(fā)送心跳監(jiān)控彼此存活的狀態(tài)笆豁。客戶端可以設置會話超時時間sessionTimeout价卤,在集群模式下劝萤,客戶端和ZooKeeper服務器斷開連接之后,只要間隔時間不超過sessionTimeout之前建立的會話依然有效慎璧。

5. 應用
?因為ZooKeeper自身的分布式一致性和特殊的數據結構床嫌,可以使用ZooKeeper解決很多分布式系統(tǒng)的問題,比如數據的發(fā)布訂閱胸私、分布式鎖厌处、Master選舉、分布式協(xié)調等功能岁疼。

  • 分布式鎖
    使用ZooKeeper的臨時有序節(jié)點這個特性阔涉,實現分布式鎖。比如命名一個臨時節(jié)點/lock捷绒,客戶端都去爭奪創(chuàng)建這個節(jié)點瑰排,創(chuàng)建成功就代表獲取鎖成功,由于只會有一個路徑相同的節(jié)點存在暖侨,其他客戶端不會再創(chuàng)建這個節(jié)點成功椭住。創(chuàng)建失敗則注冊Watcher檢測/lock節(jié)點的變化。當獲取鎖成功的客戶端執(zhí)行完自身邏輯之后去釋放鎖就是刪除/lock節(jié)點字逗,或者客戶端崩潰由于是臨時節(jié)點也會將鎖釋放京郑。其他客戶端監(jiān)聽到節(jié)點變化事件之后,再次去爭奪鎖葫掉。
  • 實現主從模式


    主從模式

    可以使用上圖的數據結構可以實現一個主從模式的服務集群傻挂,master的選舉、任務的分配挖息。/master使用一個臨時節(jié)點,所有集群中的服務器都去爭奪創(chuàng)建它兽肤,但是只要一個服務器會創(chuàng)建成功他就是master節(jié)點套腹,其他服務器就分配到/workers作為從節(jié)點,并監(jiān)聽/master節(jié)點的變化资铡。/tasks其下子節(jié)點存放待分配的任務电禀,而/assign則存放任務的分配情況。

. ZooKeeper內部原理

ZAB

?要理解ZooKeeper就必須要先理解ZAB這一部分內容比較多笤休,參考我寫的另外一篇文章ZAB協(xié)議尖飞。

請求處理

?Leader、Follower和Observer根本上都是服務器。我們在實現服務器時使
用的主要抽象概念是請求處理器政基。請求處理器是對處理流水線上不同階段的抽象贞铣。每一個服務器實現了一個請求處理器的序列。我們可以把一個處理器想象成添加到請求處理的一個元素沮明。一條請求經過服務器流水線上所有處理器的處理后被稱為得到完全處理辕坝。

請求處理器
?ZooKeeper代碼里有一個叫RequestProcessor的接口。這個接口的主要方法是processRequest荐健,它接受一個Request參數酱畅。在一條請求處理器的流水線上,對相鄰處理器的請求的處理通常通過隊列現實解耦合江场。當一個處理器有一條請求需要下一個處理器進行處理時纺酸,它將這條請求加入隊列。然后址否,它將處于等待狀態(tài)直到下一個處理器處理完此消息餐蔬。

Leader

Leade請求處理流水線
  1. PrepRequestProcessor:接受客戶端的請求并執(zhí)行這個請求,處理結果則是生成一個事務在张。
  2. ProposalRequestProcessor:準備一個提議用含,并將該提議發(fā)送給跟隨者ProposalRequestProcessor將會把所有請求都轉發(fā)CommitRequestProcessor,而且帮匾,對于寫操作請求啄骇,還會將請求轉發(fā)給SyncRequestProcessor處理器。
  3. SyncRequestProcessor:負責將事務持久化到磁盤上瘟斜。實際上就是將事務數據按順序追加到事務日志中缸夹,并生成快照數據。
  4. AckRequestProcessor:一個簡單請求處理器螺句,它僅僅生成確認消息并返回給自己虽惭。
  5. CommitRequestProcessor:會將收到足夠多的確認消息的提議進行提交。
  6. ToBeAppliedRequestProcessor:這個處理器會從提議列表中刪除那些待接受的提議在FinalRequestProcessor處理器執(zhí)行后刪除這個列表中的元素蛇尚。
  7. FinalRequestProcessor:處理更新類型的請求芽唇,并執(zhí)行讀取請求。

Follower

Follower請求處理流水線
  1. FollowerRequestProcessor :轉發(fā)請求給CommitRequestProcessor取劫,同時也會轉發(fā)寫請求到群首服務器匆笤。
  2. CommitRequestProcessor:直接轉發(fā)讀取請求到FinalRequestProcessor處理器,而且對于寫請求谱邪,為了保證執(zhí)行的順序炮捧,CommitRequestProcessor處理器會在收到一個寫請求處理器時暫停后續(xù)的請求處理,等待leader提交事務的消息惦银。
  3. SyncRequestProcessor:當leader接收到寫請求時會將提案發(fā)送給每個follower咆课,當收到一個提案末誓,follower會發(fā)送這個提議到SyncRequestProcessor處理器。
  4. SendRequestProcessor:會向群首發(fā)送確認消息书蚪。

小結

?平時工作中基本都是面向數據庫的CRUD喇澡,擁有很豐富的搬磚經驗,其實代碼的質量和水平并不高善炫。如果要實現一個雖然功能很簡單撩幽,但是要求可用性和拓展性很高組件,這時候感覺自己的水平就不夠用了箩艺。所以我們?yōu)槭裁匆タ匆恍﹥?yōu)秀的項目窜醉,也不是說每一段代碼都要掌握的很詳細,而是學習其中的思想艺谆。比如zookeeper其中服務狀態(tài)的轉換榨惰、服務之間的通信、FIFO隊列静汤、ZAB協(xié)議的實現琅催、對于請求處理器一個個的抽象、數據結構的設計等等虫给,這些都是可以從中學習到的思路藤抡。將來自己遇到類似的場景,想一想別人是怎么實現的抹估,自己腦子里才有思路缠黍,實現功能很簡單,最要的是如何實現的可維護药蜻、可拓展瓷式。當然zookeeper還有很多需要學習地方,本文只是對它做一個簡單的介紹和一些核心思想的實現進行說明语泽,大家想深入了ZooKeeper還是需要參考其他資料贸典。

參考

http://zookeeper.apache.org/
《從PAXOS到ZOOKEEPER分布式一致性原理與實踐》
《ZooKeeper:分布式過程協(xié)同技術詳解》
《Zab: A simple totally ordered broadcast protocol》

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市踱卵,隨后出現的幾起案子廊驼,更是在濱河造成了極大的恐慌,老刑警劉巖惋砂,帶你破解...
    沈念sama閱讀 221,576評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件妒挎,死亡現場離奇詭異,居然都是意外死亡班利,警方通過查閱死者的電腦和手機,發(fā)現死者居然都...
    沈念sama閱讀 94,515評論 3 399
  • 文/潘曉璐 我一進店門榨呆,熙熙樓的掌柜王于貴愁眉苦臉地迎上來罗标,“玉大人庸队,你說我怎么就攤上這事〈掣睿” “怎么了彻消?”我有些...
    開封第一講書人閱讀 168,017評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長宙拉。 經常有香客問我宾尚,道長,這世上最難降的妖魔是什么谢澈? 我笑而不...
    開封第一講書人閱讀 59,626評論 1 296
  • 正文 為了忘掉前任煌贴,我火速辦了婚禮,結果婚禮上锥忿,老公的妹妹穿的比我還像新娘牛郑。我一直安慰自己,他們只是感情好敬鬓,可當我...
    茶點故事閱讀 68,625評論 6 397
  • 文/花漫 我一把揭開白布淹朋。 她就那樣靜靜地躺著,像睡著了一般钉答。 火紅的嫁衣襯著肌膚如雪础芍。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,255評論 1 308
  • 那天数尿,我揣著相機與錄音仑性,去河邊找鬼。 笑死砌创,一個胖子當著我的面吹牛虏缸,可吹牛的內容都是我干的。 我是一名探鬼主播嫩实,決...
    沈念sama閱讀 40,825評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼刽辙,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了甲献?” 一聲冷哼從身側響起宰缤,我...
    開封第一講書人閱讀 39,729評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎晃洒,沒想到半個月后慨灭,有當地人在樹林里發(fā)現了一具尸體,經...
    沈念sama閱讀 46,271評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡球及,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 38,363評論 3 340
  • 正文 我和宋清朗相戀三年氧骤,在試婚紗的時候發(fā)現自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片吃引。...
    茶點故事閱讀 40,498評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡筹陵,死狀恐怖刽锤,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情朦佩,我是刑警寧澤并思,帶...
    沈念sama閱讀 36,183評論 5 350
  • 正文 年R本政府宣布,位于F島的核電站语稠,受9級特大地震影響宋彼,放射性物質發(fā)生泄漏。R本人自食惡果不足惜仙畦,卻給世界環(huán)境...
    茶點故事閱讀 41,867評論 3 333
  • 文/蒙蒙 一输涕、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧议泵,春花似錦占贫、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,338評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至碉京,卻和暖如春厢汹,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背谐宙。 一陣腳步聲響...
    開封第一講書人閱讀 33,458評論 1 272
  • 我被黑心中介騙來泰國打工烫葬, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人凡蜻。 一個月前我還...
    沈念sama閱讀 48,906評論 3 376
  • 正文 我出身青樓搭综,卻偏偏與公主長得像,于是被迫代替她去往敵國和親划栓。 傳聞我的和親對象是個殘疾皇子兑巾,可洞房花燭夜當晚...
    茶點故事閱讀 45,507評論 2 359

推薦閱讀更多精彩內容