前言
相信大家對 ZooKeeper 應(yīng)該不算陌生爽彤。但是你真的了解 ZooKeeper 是個什么東西嗎截粗?如果別人/面試官讓你給他講講?ZooKeeper 是個什么東西巨税,你能回答到什么地步呢疫稿?
我本人曾經(jīng)使用過 ZooKeeper 作為 Dubbo 的注冊中心某弦,另外在搭建 solr 集群的時候,我使用到了?ZooKeeper 作為 solr 集群的管理工具而克。前幾天靶壮,總結(jié)項目經(jīng)驗的時候,我突然問自己 ZooKeeper 到底是個什么東西员萍?想了半天腾降,腦海中只是簡單的能浮現(xiàn)出幾句話:“①Zookeeper 可以被用作注冊中心。 ②Zookeeper 是 Hadoop 生態(tài)系統(tǒng)的一員碎绎;③構(gòu)建 Zookeeper 集群的時候螃壤,使用的服務(wù)器最好是奇數(shù)臺〗钐” 可見奸晴,我對于 Zookeeper 的理解僅僅是停留在了表面。
所以日麸,通過本文寄啼,希望帶大家稍微詳細的了解一下 ZooKeeper 。如果沒有學過 ZooKeeper 代箭,那么本文將會是你進入 ZooKeeper 大門的墊腳磚墩划。如果你已經(jīng)接觸過 ZooKeeper ,那么本文將帶你回顧一下 ZooKeeper 的一些基礎(chǔ)概念嗡综。
最后乙帮,本文只涉及 ZooKeeper 的一些概念,并不涉及 ZooKeeper 的使用以及 ZooKeeper 集群的搭建极景。網(wǎng)上有介紹 ZooKeeper 的使用以及搭建 ZooKeeper 集群的文章察净,大家有需要可以自行查閱驾茴。
一 什么是 ZooKeeper
ZooKeeper 的由來
下面這段內(nèi)容摘自《從Paxos到Zookeeper 》第四章第一節(jié)的某段內(nèi)容,推薦大家閱讀以下:
Zookeeper最早起源于雅虎研究院的一個研究小組氢卡。在當時沟涨,研究人員發(fā)現(xiàn),在雅虎內(nèi)部很多大型系統(tǒng)基本都需要依賴一個類似的系統(tǒng)來進行分布式協(xié)調(diào)异吻,但是這些系統(tǒng)往往都存在分布式單點問題裹赴。所以,雅虎的開發(fā)人員就試圖開發(fā)一個通用的無單點問題的分布式協(xié)調(diào)框架诀浪,以便讓開發(fā)人員將精力集中在處理業(yè)務(wù)邏輯上棋返。
關(guān)于“ZooKeeper”這個項目的名字,其實也有一段趣聞雷猪。在立項初期睛竣,考慮到之前內(nèi)部很多項目都是使用動物的名字來命名的(例如著名的Pig項目),雅虎的工程師希望給這個項目也取一個動物的名字。時任研究院的首席科學家RaghuRamakrishnan開玩笑地說:“在這樣下去求摇,我們這兒就變成動物園了射沟!”此話一出,大家紛紛表示就叫動物園管理員吧一一一因為各個以動物命名的分布式組件放在一起与境,雅虎的整個分布式系統(tǒng)看上去就像一個大型的動物園了验夯,而Zookeeper正好要用來進行分布式環(huán)境的協(xié)調(diào)一一于是,Zookeeper的名字也就由此誕生了摔刁。
1.1 ZooKeeper 概覽
ZooKeeper 是一個開源的分布式協(xié)調(diào)服務(wù)挥转,ZooKeeper框架最初是在“Yahoo!"上構(gòu)建的,用于以簡單而穩(wěn)健的方式訪問他們的應(yīng)用程序共屈。 后來绑谣,Apache ZooKeeper成為Hadoop,HBase和其他分布式框架使用的有組織服務(wù)的標準拗引。 例如借宵,Apache HBase使用ZooKeeper跟蹤分布式數(shù)據(jù)的狀態(tài)。ZooKeeper 的設(shè)計目標是將那些復雜且容易出錯的分布式一致性服務(wù)封裝起來矾削,構(gòu)成一個高效可靠的原語集壤玫,并以一系列簡單易用的接口提供給用戶使用。
原語:操作系統(tǒng)或計算機網(wǎng)絡(luò)用語范疇怔软。是由若干條指令組成的垦细,用于完成一定功能的一個過程。具有不可分割性·即原語的執(zhí)行必須是連續(xù)的挡逼,在執(zhí)行過程中不允許被中斷。
ZooKeeper 是一個典型的分布式數(shù)據(jù)一致性解決方案腻豌,分布式應(yīng)用程序可以基于 ZooKeeper 實現(xiàn)諸如數(shù)據(jù)發(fā)布/訂閱家坎、負載均衡嘱能、命名服務(wù)、分布式協(xié)調(diào)/通知虱疏、集群管理惹骂、Master 選舉、分布式鎖和分布式隊列等功能做瞪。
Zookeeper 一個最常用的使用場景就是用于擔任服務(wù)生產(chǎn)者和服務(wù)消費者的注冊中心对粪。服務(wù)生產(chǎn)者將自己提供的服務(wù)注冊到Zookeeper中心,服務(wù)的消費者在進行服務(wù)調(diào)用的時候先到Zookeeper中查找服務(wù)装蓬,獲取到服務(wù)生產(chǎn)者的詳細信息之后著拭,再去調(diào)用服務(wù)生產(chǎn)者的內(nèi)容與數(shù)據(jù)。如下圖所示牍帚,在 Dubbo架構(gòu)中 Zookeeper 就擔任了注冊中心這一角色儡遮。
網(wǎng)絡(luò)異常
取消
重新上傳
Dubbo
1.2 結(jié)合個人使用情況的講一下 ZooKeeper
在我自己做過的項目中,主要使用到了 ZooKeeper 作為 Dubbo 的注冊中心(Dubbo 官方推薦使用 ZooKeeper注冊中心)暗赶。另外在搭建 solr 集群的時候鄙币,我使用?ZooKeeper 作為 solr 集群的管理工具。這時蹂随,ZooKeeper 主要提供下面幾個功能:1十嘿、集群管理:容錯、負載均衡岳锁。2详幽、配置文件的集中管理3、集群的入口浸锨。
我個人覺得在使用 ZooKeeper 的時候唇聘,最好是使用 集群版的 ZooKeeper 而不是單機版的。官網(wǎng)給出的架構(gòu)圖就描述的是一個集群版的 ZooKeeper 柱搜。通常 3 臺服務(wù)器就可以構(gòu)成一個?ZooKeeper?集群了迟郎。
為什么最好使用奇數(shù)臺服務(wù)器構(gòu)成 ZooKeeper 集群?
我們知道在Zookeeper中 Leader 選舉算法采用了Zab協(xié)議聪蘸。Zab核心思想是當多數(shù) Server 寫成功宪肖,則任務(wù)數(shù)據(jù)寫成功。
①如果有3個Server健爬,則最多允許1個Server 掛掉控乾。
②如果有4個Server,則同樣最多允許1個Server掛掉娜遵。
既然3個或者4個Server蜕衡,同樣最多允許1個Server掛掉,那么它們的可靠性是一樣的设拟,所以選擇奇數(shù)個ZooKeeper Server即可慨仿,這里選擇3個Server久脯。
二 關(guān)于 ZooKeeper?的一些重要概念
2.1 重要概念總結(jié)
ZooKeeper?本身就是一個分布式程序(只要半數(shù)以上節(jié)點存活,ZooKeeper?就能正常服務(wù))镰吆。
為了保證高可用帘撰,最好是以集群形態(tài)來部署 ZooKeeper,這樣只要集群中大部分機器是可用的(能夠容忍一定的機器故障)万皿,那么 ZooKeeper 本身仍然是可用的摧找。
ZooKeeper?將數(shù)據(jù)保存在內(nèi)存中,這也就保證了 高吞吐量和低延遲(但是內(nèi)存限制了能夠存儲的容量不太大牢硅,此限制也是保持znode中存儲的數(shù)據(jù)量較小的進一步原因)蹬耘。
ZooKeeper 是高性能的。 在“讀”多于“寫”的應(yīng)用程序中尤其地高性能唤衫,因為“寫”會導致所有的服務(wù)器間同步狀態(tài)婆赠。(“讀”多于“寫”是協(xié)調(diào)服務(wù)的典型場景。)
ZooKeeper有臨時節(jié)點的概念佳励。 當創(chuàng)建臨時節(jié)點的客戶端會話一直保持活動休里,瞬時節(jié)點就一直存在。而當會話終結(jié)時赃承,瞬時節(jié)點被刪除妙黍。持久節(jié)點是指一旦這個ZNode被創(chuàng)建了,除非主動進行ZNode的移除操作瞧剖,否則這個ZNode將一直保存在Zookeeper上拭嫁。
ZooKeeper 底層其實只提供了兩個功能:①管理(存儲、讀茸ビ凇)用戶程序提交的數(shù)據(jù)做粤;②為用戶程序提交數(shù)據(jù)節(jié)點監(jiān)聽服務(wù)。
下面關(guān)于會話(Session)捉撮、 Znode怕品、版本、Watcher巾遭、ACL概念的總結(jié)都在《從Paxos到Zookeeper 》第四章第一節(jié)以及第七章第八節(jié)有提到肉康,感興趣的可以看看!
2.2 會話(Session)
Session 指的是 ZooKeeper?服務(wù)器與客戶端會話灼舍。在 ZooKeeper 中吼和,一個客戶端連接是指客戶端和服務(wù)器之間的一個 TCP 長連接∑锼兀客戶端啟動的時候炫乓,首先會與服務(wù)器建立一個 TCP 連接,從第一次連接建立開始,客戶端會話的生命周期也開始了厢岂。通過這個連接光督,客戶端能夠通過心跳檢測與服務(wù)器保持有效的會話阳距,也能夠向Zookeeper服務(wù)器發(fā)送請求并接受響應(yīng)塔粒,同時還能夠通過該連接接收來自服務(wù)器的Watch事件通知。Session的sessionTimeout值用來設(shè)置一個客戶端會話的超時時間筐摘。當由于服務(wù)器壓力太大卒茬、網(wǎng)絡(luò)故障或是客戶端主動斷開連接等各種原因?qū)е驴蛻舳诉B接斷開時,只要在sessionTimeout規(guī)定的時間內(nèi)能夠重新連接上集群中任意一臺服務(wù)器咖熟,那么之前創(chuàng)建的會話仍然有效圃酵。
在為客戶端創(chuàng)建會話之前,服務(wù)端首先會為每個客戶端都分配一個sessionID馍管。由于 sessionID 是 Zookeeper 會話的一個重要標識郭赐,許多與會話相關(guān)的運行機制都是基于這個 sessionID 的,因此确沸,無論是哪臺服務(wù)器為客戶端分配的 sessionID捌锭,都務(wù)必保證全局唯一。
2.3 Znode
在談到分布式的時候罗捎,我們通常說的“節(jié)點"是指組成集群的每一臺機器观谦。然而,在Zookeeper中桨菜,“節(jié)點"分為兩類豁状,第一類同樣是指構(gòu)成集群的機器,我們稱之為機器節(jié)點倒得;第二類則是指數(shù)據(jù)模型中的數(shù)據(jù)單元泻红,我們稱之為數(shù)據(jù)節(jié)點一一ZNode。
Zookeeper將所有數(shù)據(jù)存儲在內(nèi)存中霞掺,數(shù)據(jù)模型是一棵樹(Znode Tree)谊路,由斜杠(/)的進行分割的路徑,就是一個Znode根悼,例如/foo/path1凶异。每個上都會保存自己的數(shù)據(jù)內(nèi)容,同時還會保存一系列屬性信息挤巡。
在Zookeeper中剩彬,node可以分為持久節(jié)點和臨時節(jié)點兩類。所謂持久節(jié)點是指一旦這個ZNode被創(chuàng)建了矿卑,除非主動進行ZNode的移除操作喉恋,否則這個ZNode將一直保存在Zookeeper上。而臨時節(jié)點就不一樣了,它的生命周期和客戶端會話綁定轻黑,一旦客戶端會話失效糊肤,那么這個客戶端創(chuàng)建的所有臨時節(jié)點都會被移除。另外氓鄙,ZooKeeper還允許用戶為每個節(jié)點添加一個特殊的屬性:SEQUENTIAL.一旦節(jié)點被標記上這個屬性馆揉,那么在這個節(jié)點被創(chuàng)建的時候,Zookeeper會自動在其節(jié)點名后面追加上一個整型數(shù)字抖拦,這個整型數(shù)字是一個由父節(jié)點維護的自增數(shù)字升酣。
2.4 版本
在前面我們已經(jīng)提到,Zookeeper 的每個 ZNode 上都會存儲數(shù)據(jù)态罪,對應(yīng)于每個ZNode噩茄,Zookeeper 都會為其維護一個叫作Stat的數(shù)據(jù)結(jié)構(gòu),Stat中記錄了這個 ZNode 的三個數(shù)據(jù)版本复颈,分別是version(當前ZNode的版本)绩聘、cversion(當前ZNode子節(jié)點的版本)和 cversion(當前ZNode的ACL版本)。
2.5 Watcher
Watcher(事件監(jiān)聽器)耗啦,是Zookeeper中的一個很重要的特性凿菩。Zookeeper允許用戶在指定節(jié)點上注冊一些Watcher,并且在一些特定事件觸發(fā)的時候芹彬,ZooKeeper服務(wù)端會將事件通知到感興趣的客戶端上去蓄髓,該機制是Zookeeper實現(xiàn)分布式協(xié)調(diào)服務(wù)的重要特性。
2.6 ACL
Zookeeper采用ACL(AccessControlLists)策略來進行權(quán)限控制舒帮,類似于 UNIX 文件系統(tǒng)的權(quán)限控制会喝。Zookeeper 定義了如下5種權(quán)限。
網(wǎng)絡(luò)異常
取消
重新上傳
其中尤其需要注意的是玩郊,CREATE和DELETE這兩種權(quán)限都是針對子節(jié)點的權(quán)限控制肢执。
三 ZooKeeper 特點
順序一致性:從同一客戶端發(fā)起的事務(wù)請求,最終將會嚴格地按照順序被應(yīng)用到 ZooKeeper 中去译红。
原子性:所有事務(wù)請求的處理結(jié)果在整個集群中所有機器上的應(yīng)用情況是一致的预茄,也就是說,要么整個集群中所有的機器都成功應(yīng)用了某一個事務(wù)侦厚,要么都沒有應(yīng)用耻陕。
單一系統(tǒng)映像 :無論客戶端連到哪一個 ZooKeeper 服務(wù)器上,其看到的服務(wù)端數(shù)據(jù)模型都是一致的刨沦。
可靠性:一旦一次更改請求被應(yīng)用诗宣,更改的結(jié)果就會被持久化,直到被下一次更改覆蓋想诅。
四 ZooKeeper 設(shè)計目標
4.1 簡單的數(shù)據(jù)模型
ZooKeeper 允許分布式進程通過共享的層次結(jié)構(gòu)命名空間進行相互協(xié)調(diào)召庞,這與標準文件系統(tǒng)類似岛心。 名稱空間由 ZooKeeper 中的數(shù)據(jù)寄存器組成 - 稱為znode,這些類似于文件和目錄篮灼。 與為存儲設(shè)計的典型文件系統(tǒng)不同忘古,ZooKeeper數(shù)據(jù)保存在內(nèi)存中,這意味著ZooKeeper可以實現(xiàn)高吞吐量和低延遲诅诱。
網(wǎng)絡(luò)異常
取消
重新上傳
4.2 可構(gòu)建集群
為了保證高可用髓堪,最好是以集群形態(tài)來部署 ZooKeeper,這樣只要集群中大部分機器是可用的(能夠容忍一定的機器故障)逢艘,那么zookeeper本身仍然是可用的旦袋。客戶端在使用 ZooKeeper 時骤菠,需要知道集群機器列表它改,通過與集群中的某一臺機器建立 TCP 連接來使用服務(wù),客戶端使用這個TCP鏈接來發(fā)送請求商乎、獲取結(jié)果央拖、獲取監(jiān)聽事件以及發(fā)送心跳包。如果這個連接異常斷開了鹉戚,客戶端可以連接到另外的機器上鲜戒。
ZooKeeper 官方提供的架構(gòu)圖:
網(wǎng)絡(luò)異常
取消
重新上傳
上圖中每一個Server代表一個安裝Zookeeper服務(wù)的服務(wù)器。組成 ZooKeeper 服務(wù)的服務(wù)器都會在內(nèi)存中維護當前的服務(wù)器狀態(tài)抹凳,并且每臺服務(wù)器之間都互相保持著通信遏餐。集群間通過 Zab 協(xié)議(Zookeeper Atomic Broadcast)來保持數(shù)據(jù)的一致性。
4.3 順序訪問
對于來自客戶端的每個更新請求赢底,ZooKeeper 都會分配一個全局唯一的遞增編號失都,這個編號反應(yīng)了所有事務(wù)操作的先后順序,應(yīng)用程序可以使用 ZooKeeper 這個特性來實現(xiàn)更高層次的同步原語幸冻。這個編號也叫做時間戳——zxid(Zookeeper Transaction Id)
4.4 高性能
ZooKeeper 是高性能的粹庞。 在“讀”多于“寫”的應(yīng)用程序中尤其地高性能,因為“寫”會導致所有的服務(wù)器間同步狀態(tài)洽损。(“讀”多于“寫”是協(xié)調(diào)服務(wù)的典型場景庞溜。)
五 ZooKeeper 集群角色介紹
最典型集群模式: Master/Slave 模式(主備模式)。在這種模式中碑定,通常 Master服務(wù)器作為主服務(wù)器提供寫服務(wù)流码,其他的 Slave 服務(wù)器從服務(wù)器通過異步復制的方式獲取 Master 服務(wù)器最新的數(shù)據(jù)提供讀服務(wù)。
但是延刘,在 ZooKeeper 中沒有選擇傳統(tǒng)的?Master/Slave 概念谴蔑,而是引入了Leader、Follower 和 Observer 三種角色屋讶。如下圖所示
網(wǎng)絡(luò)異常
取消
重新上傳
ZooKeeper 集群中的所有機器通過一個 Leader 選舉過程來選定一臺稱為 “Leader” 的機器怀酷,Leader 既可以為客戶端提供寫服務(wù)又能提供讀服務(wù)觉阅。除了 Leader 外,F(xiàn)ollower 和?Observer 都只能提供讀服務(wù)秘车。Follower 和?Observer 唯一的區(qū)別在于 Observer 機器不參與 Leader 的選舉過程典勇,也不參與寫操作的“過半寫成功”策略,因此 Observer 機器可以在不影響寫性能的情況下提升集群的讀性能叮趴。
網(wǎng)絡(luò)異常
取消
重新上傳
六 ZooKeeper &ZAB 協(xié)議&Paxos算法
6.1 ZAB 協(xié)議&Paxos算法
Paxos 算法應(yīng)該可以說是?ZooKeeper 的靈魂了割笙。但是,ZooKeeper 并沒有完全采用 Paxos算法 眯亦,而是使用 ZAB 協(xié)議作為其保證數(shù)據(jù)一致性的核心算法伤溉。另外,在ZooKeeper的官方文檔中也指出妻率,ZAB協(xié)議并不像 Paxos 算法那樣乱顾,是一種通用的分布式一致性算法,它是一種特別為Zookeeper設(shè)計的崩潰可恢復的原子消息廣播算法宫静。
6.2 ZAB 協(xié)議介紹
ZAB(ZooKeeper Atomic Broadcast 原子廣播) 協(xié)議是為分布式協(xié)調(diào)服務(wù) ZooKeeper 專門設(shè)計的一種支持崩潰恢復的原子廣播協(xié)議走净。 在 ZooKeeper 中,主要依賴 ZAB 協(xié)議來實現(xiàn)分布式數(shù)據(jù)一致性孤里,基于該協(xié)議伏伯,ZooKeeper 實現(xiàn)了一種主備模式的系統(tǒng)架構(gòu)來保持集群中各個副本之間的數(shù)據(jù)一致性。
6.3 ZAB 協(xié)議兩種基本的模式:崩潰恢復和消息廣播
ZAB協(xié)議包括兩種基本的模式捌袜,分別是崩潰恢復和消息廣播说搅。當整個服務(wù)框架在啟動過程中,或是當 Leader 服務(wù)器出現(xiàn)網(wǎng)絡(luò)中斷虏等、崩潰退出與重啟等異常情況時弄唧,ZAB 協(xié)議就會進人恢復模式并選舉產(chǎn)生新的Leader服務(wù)器。當選舉產(chǎn)生了新的 Leader 服務(wù)器博其,同時集群中已經(jīng)有過半的機器與該Leader服務(wù)器完成了狀態(tài)同步之后套才,ZAB協(xié)議就會退出恢復模式。其中慕淡,所謂的狀態(tài)同步是指數(shù)據(jù)同步背伴,用來保證集群中存在過半的機器能夠和Leader服務(wù)器的數(shù)據(jù)狀態(tài)保持一致。
當集群中已經(jīng)有過半的Follower服務(wù)器完成了和Leader服務(wù)器的狀態(tài)同步峰髓,那么整個服務(wù)框架就可以進人消息廣播模式了傻寂。當一臺同樣遵守ZAB協(xié)議的服務(wù)器啟動后加人到集群中時,如果此時集群中已經(jīng)存在一個Leader服務(wù)器在負責進行消息廣播携兵,那么新加人的服務(wù)器就會自覺地進人數(shù)據(jù)恢復模式:找到Leader所在的服務(wù)器疾掰,并與其進行數(shù)據(jù)同步,然后一起參與到消息廣播流程中去徐紧。正如上文介紹中所說的静檬,ZooKeeper設(shè)計成只允許唯一的一個Leader服務(wù)器來進行事務(wù)請求的處理炭懊。Leader服務(wù)器在接收到客戶端的事務(wù)請求后,會生成對應(yīng)的事務(wù)提案并發(fā)起一輪廣播協(xié)議拂檩;而如果集群中的其他機器接收到客戶端的事務(wù)請求侮腹,那么這些非Leader服務(wù)器會首先將這個事務(wù)請求轉(zhuǎn)發(fā)給Leader服務(wù)器。
六 總結(jié)
通過閱讀本文稻励,想必大家已從①ZooKeeper的由來父阻。->②ZooKeeper 到底是什么 。->③ ZooKeeper 的一些重要概念(會話(Session)望抽、 Znode加矛、版本、Watcher煤篙、ACL)->④ZooKeeper 的特點斟览。->⑤ZooKeeper 的設(shè)計目標。->⑥ ZooKeeper 集群角色介紹(Leader舰蟆、Follower 和 Observer 三種角色)->⑦ZooKeeper &ZAB 協(xié)議&Paxos算法趣惠。這七點了解了 ZooKeeper 。
工作一到五年的Java工程師朋友們可以加入Java架構(gòu)開發(fā):760940986
群內(nèi)提供免費的Java架構(gòu)學習資料(里面有高可用身害、高并發(fā)、高性能及分布式草戈、Jvm性能調(diào)優(yōu)塌鸯、Spring源碼,MyBatis唐片,Netty,Redis,Kafka,Mysql,Zookeeper,Tomcat,Docker,Dubbo,Nginx等多個知識點的架構(gòu)資料)合理利用自己每一分每一秒的時間來學習提升自己丙猬,不要再用"沒有時間“來掩飾自己思想上的懶惰!趁年輕费韭,使勁拼茧球,給未來的自己一個交代!