ZooKeeper為分布式應(yīng)用提供了高效且可靠的分布式協(xié)調(diào)服務(wù)龟劲,提供了諸如tong'yi統(tǒng)一命名服務(wù)、配置管理和分布式鎖等分布式的基礎(chǔ)服務(wù)轴或。在解決分布式數(shù)據(jù)一致性方面昌跌,ZooKeeper并沒有直接采用Paxos算法,而是采用了一種被稱為ZAB(ZooKeeper Atomic Broadcast)的一致性協(xié)議照雁。
一蚕愤、初始ZooKeeper
ZooKeeper是一個(gè)開放源代碼的分布式協(xié)調(diào)服務(wù),由雅虎創(chuàng)建饺蚊,是Google Chubby的開源實(shí)現(xiàn)萍诱。ZooKeeper的設(shè)計(jì)目標(biāo)是將那些復(fù)雜且容易出錯(cuò)的分布式一致性服務(wù)封裝起來,構(gòu)成一個(gè)高效可靠的原語(yǔ)集污呼,并以一系列簡(jiǎn)單易用的接口提供給用戶使用裕坊。
1. ZooKeeper介紹
1.1 ZooKeeper是什么
ZooKeeper是一個(gè)典型的分布式數(shù)據(jù)一致性的解決方案,分布式應(yīng)用程序可以基于它實(shí)現(xiàn)諸如數(shù)據(jù)發(fā)布/訂閱曙求、負(fù)載均衡碍庵、命名服務(wù)、分布式協(xié)調(diào)/通知悟狱、集群管理静浴、Master選舉、分布式鎖和分布式隊(duì)列等功能挤渐。ZooKeeper可以保證如下分布式一致性特性苹享。
順序一致性
從同一個(gè)客戶端發(fā)起的事務(wù)請(qǐng)求,最終將會(huì)嚴(yán)格按照其發(fā)起順序被應(yīng)用到ZooKeeper中去。
原子性
所有事務(wù)請(qǐng)求的處理結(jié)果在整個(gè)集群中所有機(jī)器上的應(yīng)用情況是一致的得问,也就是說囤攀,要么整個(gè)集群所有機(jī)器都成功應(yīng)用了某一個(gè)事務(wù),要么都沒有應(yīng)用宫纬,一定不會(huì)出現(xiàn)集群中部分機(jī)器應(yīng)用了該事務(wù)焚挠,而另外一部分沒有應(yīng)用的情況。
單一視圖(Single System Image)
無(wú)論客戶端連接的是哪個(gè)ZooKeeper服務(wù)器漓骚,其看到的服務(wù)端數(shù)據(jù)模型都是一致的蝌衔。
可靠性
一旦服務(wù)端成功應(yīng)用了一個(gè)事務(wù),并完成對(duì)客戶端的響應(yīng)蝌蹂,那么該事務(wù)所引起的服務(wù)端狀態(tài)變更會(huì)被一直保留下來噩斟,除非有另一個(gè)事務(wù)又對(duì)其進(jìn)行了變更。
實(shí)時(shí)性
通常人們看到實(shí)時(shí)性的第一反應(yīng)是孤个,一旦一個(gè)事務(wù)被成功應(yīng)用剃允,那么客戶端能夠立即從服務(wù)端上讀取到這個(gè)事務(wù)變更后的最新數(shù)據(jù)狀態(tài)。這里需要注意的是齐鲤,ZooKeeper僅僅保證在一定的時(shí)間段內(nèi)斥废,客戶端最終一定能夠從服務(wù)端上讀取到最新的數(shù)據(jù)狀態(tài)。
1.2 ZooKeeper的設(shè)計(jì)目標(biāo)
ZooKeeper致力于提供一個(gè)高性能给郊、高可用营袜,且具有嚴(yán)格的順序訪問控制能力(主要是寫操作的嚴(yán)格順序性)的分布式協(xié)調(diào)服務(wù)。高性能使得ZooKeeper能夠應(yīng)用于那些對(duì)系統(tǒng)吞吐有明確要求的大型分布式系統(tǒng)中丑罪,高可用使得分布式的單點(diǎn)問題得到了很好地解決荚板,而嚴(yán)格的順序訪問控制使得客戶端能夠基于ZooKeeper實(shí)現(xiàn)一些復(fù)雜的同步原語(yǔ)。
目標(biāo)一:簡(jiǎn)單的數(shù)據(jù)模型
ZooKeeper使得分布式程序能夠通過一個(gè)共享的吩屹、樹形結(jié)構(gòu)的名字空間來進(jìn)行相互協(xié)調(diào)跪另。這里所說的樹形結(jié)構(gòu)的名字空間,是指ZooKeeper服務(wù)器內(nèi)存中的一個(gè)數(shù)據(jù)模型煤搜,其you由一系列被稱為ZNode的數(shù)據(jù)節(jié)點(diǎn)組成免绿,總的來說,其數(shù)據(jù)模型類似于一個(gè)文件系統(tǒng)擦盾,而ZNode之間的層級(jí)關(guān)系嘲驾,就像文件系統(tǒng)的目錄結(jié)構(gòu)一樣。不過和傳統(tǒng)的磁盤文件系統(tǒng)不同的是迹卢,ZooKeeper將全量數(shù)據(jù)存儲(chǔ)在內(nèi)存中辽故,以此來提高服務(wù)器吞吐、減少延遲的目的腐碱。
目標(biāo)二:可以構(gòu)建集群
一個(gè)ZooKeeper集群通常由一組機(jī)器組成誊垢,一般3-5臺(tái)機(jī)器就可以組成一個(gè)可用的ZooKeeper集群。
組成ZooKeeper集群的每臺(tái)機(jī)器都會(huì)在內(nèi)存中維護(hù)當(dāng)前的服務(wù)器狀態(tài),并且每臺(tái)機(jī)器之間都互相保持著通信喂走。值得一提的是殃饿,只要集群中存在超過一半的機(jī)器能正常工作,整個(gè)集群就能正常對(duì)外提供服務(wù)芋肠。
目標(biāo)三:順序訪問
對(duì)于來自客戶端的每個(gè)更新請(qǐng)求乎芳,ZooKeeper都會(huì)分配一個(gè)全局唯一的遞增編號(hào),這個(gè)編號(hào)反映了所有事務(wù)操作的先后順序帖池,應(yīng)用程序可以使用ZooKeeper這個(gè)特性來實(shí)現(xiàn)更高層次的同步原語(yǔ)秒咐。
目標(biāo)四:高性能
由于ZooKeeper將全量數(shù)據(jù)存儲(chǔ)在內(nèi)存中,并直接服務(wù)于客戶端的所有非事務(wù)請(qǐng)求碘裕,因此它尤其適用于以讀操作為主的應(yīng)用場(chǎng)景。
1.2 ZooKeeper從何而來
大型動(dòng)物園的故事
1.3 ZooKeeper的基本概念
集群角色
最典型的集群模式使Master/Slave模式(主從模式)攒钳,這種模式中帮孔,能夠處理所有鞋操作的機(jī)器成為Master機(jī)器,把所有通過異步復(fù)制方式獲取最新數(shù)據(jù)不撑,并提供讀服務(wù)的機(jī)器成為Slave機(jī)器文兢。
而在ZooKeeper中,引用了Leader焕檬、Follower和Observer三種角色姆坚。ZooKeeper集群的所有機(jī)器通過一個(gè)leader選舉過程選定一臺(tái)被稱為“Leader”的機(jī)器,Leader服務(wù)器為客戶端提供讀和寫服務(wù)实愚。除Leader外兼呵,其他機(jī)器包括Follower和Observer。Follower和Observer都能提供讀服務(wù)腊敲,唯一的區(qū)別在于击喂,Observer機(jī)器不參與Leader選舉過程,也不參與寫操作的“過半寫成功”策略碰辅,因此Observer可以在不影響寫性能的情況下提升集群的讀性能懂昂。
會(huì)話(Session)
在ZooKeeper中,一個(gè)客戶端連接是指客戶端和服務(wù)器之間的一個(gè)TCP長(zhǎng)連接没宾。ZooKeeper對(duì)外的服務(wù)端口默認(rèn)是2181凌彬,客戶端啟動(dòng)的時(shí)候,首先會(huì)與服務(wù)器建立一個(gè)TCP連接循衰,從第一次連接建立開始铲敛,客戶端會(huì)話的生命周期也開始了,通過這個(gè)連接会钝,客戶端能夠通過心跳監(jiān)測(cè)與服務(wù)器保持有效的會(huì)話原探,也能夠向ZooKeeper服務(wù)器發(fā)送請(qǐng)求并接受響應(yīng),通過還能夠通過該連接接收來自服務(wù)器的Watch事件通知。Session的sessionTimeout值用來設(shè)置一個(gè)客戶端會(huì)話的超時(shí)時(shí)間咽弦。當(dāng)由于服務(wù)器壓力太大徒蟆、網(wǎng)絡(luò)故障或是客戶端主動(dòng)斷開連接等各種原因?qū)е驴蛻舳诉B接斷開時(shí),只要在sessionTimeout規(guī)定的時(shí)間內(nèi)能夠重新連上集群中任意一臺(tái)服務(wù)器型型,那么值錢創(chuàng)建的會(huì)話仍然有效段审。
數(shù)據(jù)節(jié)點(diǎn)(Znode)
在ZooKeeper中,“節(jié)點(diǎn)”分為兩類闹蒜,第一類同樣是構(gòu)成集群的機(jī)器節(jié)點(diǎn)寺枉;第二類則是數(shù)據(jù)模型中的數(shù)據(jù)單元,我們稱之為數(shù)據(jù)節(jié)點(diǎn)--ZNode绷落。ZooKeeper將所有數(shù)據(jù)存儲(chǔ)在內(nèi)存中姥闪,數(shù)據(jù)模型是一棵樹(ZNode Tree),由斜杠(/)進(jìn)行分割的路徑砌烁,就是一個(gè)Znode筐喳。每個(gè)ZNode上都會(huì)保存自己的數(shù)據(jù)內(nèi)容,同時(shí)還會(huì)保存一系列屬性信息函喉。
ZNode可以分為持久節(jié)點(diǎn)和臨時(shí)節(jié)點(diǎn)兩類避归。所謂持久節(jié)點(diǎn)是指一旦這個(gè)ZNode被創(chuàng)建了,除非主動(dòng)進(jìn)行移除操作管呵,否則這個(gè)ZNode將一直保存在ZooKeeper上梳毙。而臨時(shí)節(jié)點(diǎn)的生命周期和客戶端會(huì)話綁定,一旦客戶端會(huì)話失效捐下,那么這個(gè)客戶端創(chuàng)建的所有臨時(shí)節(jié)點(diǎn)都會(huì)被移除账锹。另外冠跷,ZooKeeper還允許用戶為每個(gè)節(jié)點(diǎn)添加一個(gè)特殊的屬性:SEQUENTIAL噪窘。一旦節(jié)點(diǎn)被標(biāo)記上這個(gè)屬性斜筐,那么這個(gè)節(jié)點(diǎn)被創(chuàng)建的時(shí)候请毛,ZooKeeper會(huì)自動(dòng)在其節(jié)點(diǎn)名后面追加上一個(gè)整形數(shù)字榨乎,這個(gè)整型數(shù)字是一個(gè)由父節(jié)點(diǎn)維護(hù)的自增數(shù)字节槐。
版本
對(duì)于每個(gè)ZNode鸭限,ZooKeeper都會(huì)為其維護(hù)一個(gè)叫做Stat的數(shù)據(jù)結(jié)構(gòu)闰蚕,Stat中記錄了這個(gè)ZNode的三個(gè)數(shù)據(jù)版本排抬,分別是version(當(dāng)前ZNode的版本)懂从、cversion(當(dāng)前ZNode子節(jié)點(diǎn)的版本)和aversion(當(dāng)前ZNode的ACL版本)。
Watcher
Watcher(事件監(jiān)聽器)蹲蒲。ZooKeeper允許用戶在制定節(jié)點(diǎn)上注冊(cè)一些Watcher番甩,并且在一些特定事件觸發(fā)的時(shí)候,ZooKeeper服務(wù)端會(huì)將事件通知到感興趣的客戶端上去届搁,該機(jī)制是ZooKeeper實(shí)現(xiàn)分布式協(xié)調(diào)服務(wù)的重要特性缘薛。
ACL(Access Control Lists)
實(shí)現(xiàn)權(quán)限控制窍育,定義了5種權(quán)限:
- CREATE
- READ
- WRITE
- DELETE
- ADMIN
1.4 為什么選擇ZooKeeper
- 已經(jīng)達(dá)到了一個(gè)工業(yè)級(jí)產(chǎn)品的標(biāo)準(zhǔn)
- 開放源代碼
- 免費(fèi)
- 已經(jīng)得到了廣泛的應(yīng)用,諸如Hadoop宴胧、HBase漱抓、Storm和Solr。
二恕齐、ZooKeeper的ZAB協(xié)議
2.1 ZAB協(xié)議
ZooKeeper并沒有完全采用Paxos算法乞娄,而是使用了一種稱為ZooKeeper Atomic Broadcast(ZAB,ZooKeeper原子消息廣播協(xié)議)的協(xié)議作為其數(shù)據(jù)一致性的核心算法显歧。ZAB協(xié)議是為分布式協(xié)調(diào)服務(wù)ZooKeeper專門設(shè)計(jì)的一種支持崩潰恢復(fù)的原子廣播協(xié)議仪或。
在ZooKeeper中,主要依賴ZAB協(xié)議來實(shí)現(xiàn)分布式數(shù)據(jù)一致性士骤,基于該協(xié)議范删,ZooKeeper實(shí)現(xiàn)了一種主備模式的系統(tǒng)架構(gòu)來保持集群中各副本之間的數(shù)據(jù)一致性。具體的拷肌,ZooKeeper使用一個(gè)單一的主進(jìn)程來接收并處理客戶端的所有事務(wù)請(qǐng)求到旦,并采用ZAB的原子廣播協(xié)議,將服務(wù)器數(shù)據(jù)的狀態(tài)變更為事務(wù)Proposal的形式廣播到所有的副本進(jìn)程上去廓块。ZAB協(xié)議的這個(gè)主備模型架構(gòu)保證了同一時(shí)刻集群中只能夠有一個(gè)主進(jìn)程來廣播服務(wù)器的狀態(tài)變更,因此能夠很好地處理客戶端大量的并發(fā)請(qǐng)求契沫。另一方面带猴,考慮到在分布式環(huán)境中,順序執(zhí)行的一些狀態(tài)變更其前后會(huì)存在一定的依賴關(guān)系懈万,有些狀態(tài)變更必須依賴于比他早生成的那些狀態(tài)變更拴清。這樣的依賴關(guān)系也對(duì)ZAB協(xié)議提出了一個(gè)要求:ZAB協(xié)議必須保證一個(gè)全局的變更序列被順序應(yīng)用,也就是說会通,ZAB協(xié)議需要保證如果一個(gè)狀態(tài)變更已經(jīng)被處理了口予,那么所有其依賴的狀態(tài)變更都應(yīng)該已經(jīng)被提前處理掉了。最后涕侈,考慮到主進(jìn)程在任何時(shí)候都有可能出現(xiàn)崩潰退出或重啟現(xiàn)象沪停,因此,ZAB協(xié)議還需要坐到在當(dāng)前主進(jìn)程出現(xiàn)上述異常情況時(shí)裳涛,依舊能夠正常工作木张。
2.2 協(xié)議介紹
ZAB協(xié)議包括兩種基本的模式:崩潰恢復(fù)和消息廣播。當(dāng)服務(wù)框架在啟動(dòng)過程中端三,或是當(dāng)Leader服務(wù)器出現(xiàn)網(wǎng)絡(luò)中斷舷礼、崩潰退出與重啟等異常情況時(shí),ZAB協(xié)議就會(huì)進(jìn)入恢復(fù)模式并選舉產(chǎn)生新的Leader郊闯。當(dāng)Leader產(chǎn)生妻献,同時(shí)集群中過半機(jī)器與該Leader服務(wù)器完成狀態(tài)同步之后蛛株,ZAB就會(huì)退出恢復(fù)模式。
當(dāng)集群中有過半的Follower和Leader完成狀態(tài)同步后育拨,那么整個(gè)服務(wù)框架就可以進(jìn)入消息廣播模式了谨履。
消息廣播
ZAB協(xié)議的消息廣播過程使用的是一個(gè)原子廣播協(xié)議。針對(duì)客戶端的事務(wù)請(qǐng)求至朗,Leader服務(wù)器會(huì)為其生成對(duì)于的事務(wù)Proposal屉符,并將其發(fā)送給集群中所有的機(jī)器,然后再分別收集各自的選票锹引,最后進(jìn)行事務(wù)提交矗钟。
崩潰恢復(fù)
一旦Leader服務(wù)器出現(xiàn)崩潰,或者由于網(wǎng)絡(luò)原因?qū)е耹eader服務(wù)器失去了與過半Follower的聯(lián)系嫌变,就會(huì)進(jìn)入崩潰恢復(fù)模式吨艇。在ZAB協(xié)議中,為了保證程序的正確運(yùn)行腾啥,整個(gè)恢復(fù)過程結(jié)束后需要選舉出一個(gè)新的Leader服務(wù)器东涡。因此,ZAB協(xié)議需要一個(gè)高效且可靠的Leader選舉算法倘待,從而確保能夠快速的選舉出新的leader疮跑。同時(shí),Leader選舉算法不僅僅需要讓Leader自己知道其自身已經(jīng)被選舉為L(zhǎng)eader凸舵,同時(shí)還需要讓集群中的所有其他機(jī)器也快速的感知到選舉產(chǎn)生的新的Leader服務(wù)器祖娘。
基本特性
- ZAB協(xié)議需要確保那些已經(jīng)在Leader服務(wù)器上提交的事務(wù)最終被所有服務(wù)器都提交。
- ZAB協(xié)議需要確保丟棄那些知道Leader服務(wù)器上被提出的事務(wù)啊奄。
數(shù)據(jù)同步
2.3 深入ZAB協(xié)議
系統(tǒng)模型
我們使用Pi和Pj分別表示兩個(gè)不同進(jìn)程渐苏,使用Cij表示進(jìn)程Pi和Pj之間的wa通信通道,并滿足如下兩個(gè)基本特性菇夸。
- 完整性(Integrity)
進(jìn)程Pj如果收到來自進(jìn)程Pi的消息m琼富,那么進(jìn)程Pi一定確實(shí)發(fā)送了消息m。
- 前置性(Prefix)
所有的消息都必須按照嚴(yán)格的先后順序來處理庄新。
問題描述
主進(jìn)程周期
為了保證主進(jìn)程每次廣播出來的事務(wù)消息都是一致的鞠眉,我們必須確保ZAB協(xié)議只有在充分完成崩潰恢復(fù)階段之后,新的主進(jìn)程才可以開始生成新的事務(wù)消息廣播择诈。為了實(shí)現(xiàn)這個(gè)目的凡蚜,我們假設(shè)各個(gè)進(jìn)程都實(shí)現(xiàn)了類似于ready(e)這樣的一個(gè)函數(shù)調(diào)用,在運(yùn)行過程中吭从,ZAB協(xié)議能夠非常明確的告知上層系統(tǒng)是否可以開始進(jìn)行事務(wù)消息的廣播朝蜘,同時(shí),在調(diào)用ready(e)函數(shù)之后涩金,ZAB還需要為當(dāng)前主進(jìn)程設(shè)置一個(gè)實(shí)例值谱醇。實(shí)例值用于唯一標(biāo)識(shí)當(dāng)前主進(jìn)程的周期暇仲,在進(jìn)行消息廣播時(shí),主進(jìn)程使用該實(shí)例值來設(shè)置事務(wù)標(biāo)識(shí)中的epoch字段--當(dāng)然副渴,ZAB需要保證實(shí)例值在不同的主進(jìn)程周期中是全部唯一的奈附。
事務(wù)
我們假設(shè)各個(gè)進(jìn)程都存在一個(gè)類似于transactions(v,z)這樣的函數(shù)調(diào)用,來實(shí)現(xiàn)主線程對(duì)狀態(tài)變更的廣播煮剧。主進(jìn)程每次對(duì)transaction(v,z)函數(shù)的調(diào)用都包含了兩個(gè)字段:實(shí)物內(nèi)容v和事務(wù)標(biāo)識(shí)z斥滤,而每一個(gè)事務(wù)標(biāo)識(shí)z=<e,c>也包含兩個(gè)組成部分,前者是主進(jìn)程周期e勉盅,后者是當(dāng)前主進(jìn)程周期內(nèi)的事務(wù)計(jì)數(shù)c佑颇。我們使用epoch(z)來表示一個(gè)事務(wù)標(biāo)識(shí)中的主進(jìn)程周期epoch,使用counter(z)來表示事務(wù)標(biāo)識(shí)中的事務(wù)計(jì)數(shù)草娜。
算法描述
整個(gè)ZAB協(xié)議主要包括消息廣播和崩潰恢復(fù)兩個(gè)過程挑胸,進(jìn)一步可以細(xì)分為三個(gè)階段,分別是發(fā)現(xiàn)(Discovery)宰闰、同步(Synchronization)和廣播(Broadcast)茬贵。組成ZAB協(xié)議的每一個(gè)分布式進(jìn)程,會(huì)循環(huán)的執(zhí)行這三個(gè)階段移袍,我們將這樣一個(gè)循環(huán)稱為一個(gè)主進(jìn)程后期解藻。
運(yùn)行分析
在ZAB協(xié)議的設(shè)計(jì)中,每一個(gè)進(jìn)程都有可能處于以下三種狀態(tài)之一葡盗。
- LOOKING:Leader選舉階段
- FOLLOWING:Follower服務(wù)器和Leader保持同步狀態(tài)
- LEADING:Leader服務(wù)器作為主進(jìn)程領(lǐng)導(dǎo)狀態(tài)
2.4 ZAB和Paxos算法的聯(lián)系和區(qū)別
聯(lián)系
- 兩者都存在一個(gè)類似于Leader進(jìn)程的角色螟左,由其負(fù)責(zé)協(xié)調(diào)多個(gè)Follower進(jìn)程的運(yùn)行。
- Leader進(jìn)程都會(huì)等待超過半數(shù)的Follower做出正確的反饋后戳粒,才會(huì)將一個(gè)提案進(jìn)行提交路狮。
- 在ZAB協(xié)議中虫啥,每個(gè)Proposal都包含一個(gè)epoch值蔚约,用來代表當(dāng)前的Leader周期,在Paxos算法中涂籽,同樣存在這樣的一個(gè)標(biāo)識(shí)苹祟,只是名字變成了Ballot。
本質(zhì)區(qū)別
兩者設(shè)計(jì)目標(biāo)不太一樣评雌。ZAB協(xié)議主要用于構(gòu)建一個(gè)高可用的分布式數(shù)據(jù)主備系統(tǒng)树枫,而Paxos算法則是用于構(gòu)建一個(gè)分布式的一致性狀態(tài)機(jī)系統(tǒng)。