Zookeeper是什么
Zookeeper 分布式服務(wù)框架是Apache Hadoop 的一個(gè)子項(xiàng)目,它主要是用來解決分布式應(yīng)用中經(jīng)常遇到的一些數(shù)據(jù)管理問題,如:統(tǒng)一命名服務(wù)、狀態(tài)同步服務(wù)、集群管理、分布式應(yīng)用配置項(xiàng)的管理等
Zookeeper 作為一個(gè)分布式的服務(wù)框架培遵,主要用來解決分布式集群中應(yīng)用系統(tǒng)的一致性問題浙芙,它能提供基于類似于文件系統(tǒng)的目錄節(jié)點(diǎn)樹方式的數(shù)據(jù)存儲(chǔ), Zookeeper 作用主要是用來維護(hù)和監(jiān)控存儲(chǔ)的數(shù)據(jù)的狀態(tài)變化籽腕,通過監(jiān)控這些數(shù)據(jù)狀態(tài)的變化嗡呼,從而達(dá)到基于數(shù)據(jù)的集群管理
簡(jiǎn)單的說,zookeeper=文件系統(tǒng)+通知機(jī)制皇耗。
Zookeeer工作原理
ZooKeeper是一個(gè)分布式的南窗,開放源碼的分布式應(yīng)用程序協(xié)調(diào)服務(wù),它包含一個(gè)簡(jiǎn)單的原語(yǔ)集郎楼,分布式應(yīng)用程序可以基于它實(shí)現(xiàn)同步服務(wù)万伤,配置維護(hù)和 命名服務(wù)等。Zookeeper是hadoop的一個(gè)子項(xiàng)目呜袁,其發(fā)展歷程無需贅述敌买。
在分布式應(yīng)用中,由于工程師不能很好地使用鎖機(jī)制阶界,以及基于消息的協(xié)調(diào)機(jī)制不適合在某些應(yīng)用中使用放妈,因此需要有一種可靠的、可擴(kuò)展的荐操、分布式的、可配置的協(xié)調(diào)機(jī)制來統(tǒng)一系統(tǒng)的狀態(tài)
Zookeeper中的元素介紹
1珍策、znode節(jié)點(diǎn)
有四種類型的znode:
PERSISTENT-持久化目錄節(jié)點(diǎn)
客戶端與zookeeper斷開連接后托启,該節(jié)點(diǎn)依舊存在PERSISTENT_SEQUENTIAL-持久化順序編號(hào)目錄節(jié)點(diǎn)
客戶端與zookeeper斷開連接后,該節(jié)點(diǎn)依舊存在攘宙,只是Zookeeper給該節(jié)點(diǎn)名稱進(jìn)行順序編號(hào)EPHEMERAL-臨時(shí)目錄節(jié)點(diǎn)
客戶端與zookeeper斷開連接后屯耸,該節(jié)點(diǎn)被刪除EPHEMERAL_SEQUENTIAL-臨時(shí)順序編號(hào)目錄節(jié)點(diǎn)
客戶端與zookeeper斷開連接后,該節(jié)點(diǎn)被刪除蹭劈,只是Zookeeper給該節(jié)點(diǎn)名稱進(jìn)行順序編號(hào)
2疗绣、NameService 命名服務(wù)
這個(gè)似乎最簡(jiǎn)單,在zookeeper的文件系統(tǒng)里創(chuàng)建一個(gè)目錄铺韧,即有唯一的path多矮。在我們使用tborg無法確定上游程序的部署機(jī)器時(shí)即可與下游程序約定好path,通過path即能互相探索發(fā)現(xiàn)
這個(gè)主要是作為分布式命名服務(wù)哈打,通過調(diào)用zk的create node api塔逃,能夠很容易創(chuàng)建一個(gè)全局唯一的path,這個(gè)path就可以作為一個(gè)名稱料仗。
3湾盗、configuration 配置管理
現(xiàn)在把這些配置全部放到zookeeper上去,保存在 Zookeeper 的某個(gè)目錄節(jié)點(diǎn)中立轧,然后所有相關(guān)應(yīng)用程序?qū)@個(gè)目錄節(jié)點(diǎn)進(jìn)行監(jiān)聽格粪,一旦配置信息發(fā)生變化躏吊,每個(gè)應(yīng)用程序就會(huì)收到 Zookeeper 的通知,然后從 Zookeeper 獲取新的配置信息應(yīng)用到系統(tǒng)中就好帐萎。
4比伏、GroupMembers 集群管理
所謂集群管理無在乎兩點(diǎn):是否有機(jī)器退出和加入、選舉master吓肋。
對(duì)于第一點(diǎn)凳怨,所有機(jī)器約定在父目錄GroupMembers下創(chuàng)建臨時(shí)目錄節(jié)點(diǎn),然后監(jiān)聽父目錄節(jié)點(diǎn)的子節(jié)點(diǎn)變化消息是鬼。一旦有機(jī)器掛掉肤舞,該機(jī)器與 zookeeper的連接斷開,其所創(chuàng)建的臨時(shí)目錄節(jié)點(diǎn)被刪除均蜜,所有其他機(jī)器都收到通知:某個(gè)兄弟目錄被刪除李剖,于是,所有人都知道了囤耳。新機(jī)器加入也是類似篙顺,所有機(jī)器收到通知:新兄弟目錄加入,highcount又有了充择。
對(duì)于第二點(diǎn)德玫,所有機(jī)器創(chuàng)建臨時(shí)順序編號(hào)目錄節(jié)點(diǎn),通過master選舉算法選舉出來椎麦。
Zookeeper中的角色介紹
client
分布式中的一個(gè)節(jié)點(diǎn)宰僧,訪問服務(wù)器的配置信息,周期性向server發(fā)送心跳包观挎,server向client回應(yīng)確認(rèn)琴儿,如果client沒有收到回應(yīng),則重定向到另一個(gè)serverserver
zookeeper中的一個(gè)節(jié)點(diǎn)嘁捷,為client提供所需的服務(wù)造成,給client回應(yīng)信息表明自己是存活的leader
連接任何一個(gè)節(jié)點(diǎn),如果節(jié)點(diǎn)出現(xiàn)故障雄嚣,leader自動(dòng)修復(fù)晒屎,在service啟動(dòng)時(shí)完成leader的選舉follower
聽從leader的指令,完成選舉工作
Leader主要有三個(gè)功能:
- 恢復(fù)數(shù)據(jù)缓升;
- 維持與follower的心跳夷磕,接收follower請(qǐng)求并判斷follower的請(qǐng)求消息類型;
- follower的消息類型主要有PING消息仔沿、REQUEST消息坐桩、ACK消息、REVALIDATE消息封锉,根據(jù)不同的消息類型绵跷,進(jìn)行不同的處理膘螟。
選舉流程
當(dāng)leader崩潰或者leader失去大多數(shù)的follower,這時(shí)候zk進(jìn)入恢復(fù)模式碾局,恢復(fù)模式需要重新選舉出一個(gè)新的leader荆残,讓所有的 Server都恢復(fù)到一個(gè)正確的狀態(tài)。Zk的選舉算法有兩種:一種是基于basic paxos實(shí)現(xiàn)的净当,另外一種是基于fast paxos算法實(shí)現(xiàn)的内斯。
系統(tǒng)默認(rèn)的選舉算法為fast paxos。
basic paxos流程:
選舉線程由當(dāng)前Server發(fā)起選舉的線程擔(dān)任像啼,其主要功能是對(duì)投票結(jié)果進(jìn)行統(tǒng)計(jì)俘闯,并選出推薦的Server;
選舉線程首先向所有Server發(fā)起一次詢問(包括自己)忽冻;
選舉線程收到回復(fù)后真朗,驗(yàn)證是否是自己發(fā)起的詢問(驗(yàn)證zxid是否一致),然后獲取對(duì)方的id(myid)僧诚,并存儲(chǔ)到當(dāng)前詢問對(duì)象列表中遮婶,最后獲取對(duì)方提議的leader相關(guān)信息(id,zxid),并將這些信息存儲(chǔ)到當(dāng)次選舉的投票記錄表中湖笨;
收到所有Server回復(fù)以后旗扑,就計(jì)算出zxid最大的那個(gè)Server,并將這個(gè)Server相關(guān)信息設(shè)置成下一次要投票的Server慈省;
線程將當(dāng)前zxid最大的Server設(shè)置為當(dāng)前Server要推薦的Leader臀防,如果此時(shí)獲勝的Server獲得n/2 + 1的Server票數(shù), 設(shè)置當(dāng)前推薦的leader為獲勝的Server辫呻,將根據(jù)獲勝的Server相關(guān)信息設(shè)置自己的狀態(tài),否則琼锋,繼續(xù)這個(gè)過程放闺,直到leader被選舉出來。
通過流程分析我們可以得出:要使Leader獲得多數(shù)Server的支持缕坎,則Server總數(shù)必須是奇數(shù)2n+1怖侦,且存活的Server的數(shù)目不得少于n+1.
fast paxos流程:
在選舉過程中,某Server首先向所有Server提議自己要成為leader谜叹,當(dāng)其它Server收到提議以后匾寝,解決epoch和 zxid的沖突,并接受對(duì)方的提議荷腊,然后向?qū)Ψ桨l(fā)送接受提議完成的消息艳悔,重復(fù)這個(gè)流程,最后一定能選舉出Leader女仰。
zookeeper中的watcher
Watcher是Zookeeper用來實(shí)現(xiàn)distribute lock, distribute configure, distribute queue等應(yīng)用的主要手段猜年。要監(jiān)控data_tree上的任何節(jié)點(diǎn)的變化(節(jié)點(diǎn)本身的增加抡锈,刪除,數(shù)據(jù)修改乔外,以及孩子的變化)都可以在獲取該數(shù)據(jù)時(shí)注冊(cè)一個(gè)Watcher床三,這有很像Listener模式。一旦該節(jié)點(diǎn)數(shù)據(jù)變化杨幼,F(xiàn)ollower會(huì)發(fā)送一個(gè)notification response撇簿,client收到notification響應(yīng),則會(huì)查找對(duì)應(yīng)的Watcher并回調(diào)他們
Client可以在某個(gè)ZNode上設(shè)置一個(gè)Watcher差购,來Watch該ZNode上的變化四瘫。如果該ZNode上有相應(yīng)的變化,就會(huì)觸發(fā)這個(gè)Watcher歹撒,把相應(yīng)的事件通知給設(shè)置Watcher的Client莲组。需要注意的是,ZooKeeper中的Watcher是一次性的暖夭,即觸發(fā)一次就會(huì)被取消锹杈,如果想繼續(xù)Watch的話,需要客戶端重新設(shè)置Watcher
atomic broadcasts原子廣播
Zookeeper的核心是原子廣播迈着,這個(gè)機(jī)制保證了各個(gè)Server之間的同步竭望。實(shí)現(xiàn)這個(gè)機(jī)制的協(xié)議叫做Zab協(xié)議。
Zab協(xié)議有兩種模式裕菠,它們分別是恢復(fù)模式(選主)和廣播模式(同步)咬清。當(dāng)服務(wù)啟動(dòng)或者在領(lǐng)導(dǎo)者崩潰后,Zab就進(jìn)入了恢復(fù)模式奴潘,當(dāng)領(lǐng)導(dǎo)者被選舉出來旧烧,且大多數(shù)Server完成了和 leader的狀態(tài)同步以后,恢復(fù)模式就結(jié)束了画髓。狀態(tài)同步保證了leader和Server具有相同的系統(tǒng)狀態(tài)
ZooKeeper Watcher 特性總結(jié)
注冊(cè)只能確保一次消費(fèi)
無論是服務(wù)端還是客戶端掘剪,一旦一個(gè) Watcher 被觸發(fā),ZooKeeper 都會(huì)將其從相應(yīng)的存儲(chǔ)中移除奈虾。因此夺谁,開發(fā)人員在 Watcher 的使用上要記住的一點(diǎn)是需要反復(fù)注冊(cè)。這樣的設(shè)計(jì)有效地減輕了服務(wù)端的壓力肉微。如果注冊(cè)一個(gè) Watcher 之后一直有效匾鸥,那么針對(duì)那些更新非常頻繁的節(jié)點(diǎn),服務(wù)端會(huì)不斷地向客戶端發(fā)送事件通知碉纳,這無論對(duì)于網(wǎng)絡(luò)還是服務(wù)端性能的影響都非常大勿负。客戶端串行執(zhí)行
客戶端 Watcher 回調(diào)的過程是一個(gè)串行同步的過程,這為我們保證了順序劳曹,同時(shí)笆环,需要開發(fā)人員注意的一點(diǎn)是攒至,千萬(wàn)不要因?yàn)橐粋€(gè) Watcher 的處理邏輯影響了整個(gè)客戶端的 Watcher 回調(diào)。輕量級(jí)設(shè)計(jì)
WatchedEvent 是 ZooKeeper 整個(gè) Watcher 通知機(jī)制的最小通知單元躁劣,這個(gè)數(shù)據(jù)結(jié)構(gòu)中只包含三部分的內(nèi)容:通知狀態(tài)迫吐、事件類型和節(jié)點(diǎn)路徑。也就是說账忘,Watcher 通知非常簡(jiǎn)單志膀,只會(huì)告訴客戶端發(fā)生了事件,而不會(huì)說明事件的具體內(nèi)容鳖擒。例如針對(duì) NodeDataChanged 事件溉浙,ZooKeeper 的 Watcher 只會(huì)通知客戶指定數(shù)據(jù)節(jié)點(diǎn)的數(shù)據(jù)內(nèi)容發(fā)生了變更,而對(duì)于原始數(shù)據(jù)以及變更后的新數(shù)據(jù)都無法從這個(gè)事件中直接獲取到蒋荚,而是需要客戶端主動(dòng)重新去獲取數(shù)據(jù)戳稽,這也是 ZooKeeper 的 Watcher 機(jī)制的一個(gè)非常重要的特性。
設(shè)計(jì)目的
最終一致性:client不論連接到哪個(gè)Server期升,展示給它都是同一個(gè)視圖惊奇,這是zookeeper最重要的性能。
可靠性:具有簡(jiǎn)單播赁、健壯颂郎、良好的性能,如果消息m被到一臺(tái)服務(wù)器接受容为,那么它將被所有的服務(wù)器接受乓序。
實(shí)時(shí)性:Zookeeper保證客戶端將在一個(gè)時(shí)間間隔范圍內(nèi)獲得服務(wù)器的更新信息,或者服務(wù)器失效的信息坎背。但由于網(wǎng)絡(luò)延時(shí)等原因替劈,Zookeeper不能保證兩個(gè)客戶端能同時(shí)得到剛更新的數(shù)據(jù),如果需要最新數(shù)據(jù)得滤,應(yīng)該在讀數(shù)據(jù)之前調(diào)用sync()接口陨献。
等待無關(guān)(wait-free):慢的或者失效的client不得干預(yù)快速的client的請(qǐng)求,使得每個(gè)client都能有效的等待耿戚。
原子性:更新只能成功或者失敗湿故,沒有中間狀態(tài)阿趁。
順序性:包括全局有序和偏序兩種:全局有序是指如果在一臺(tái)服務(wù)器上消息a在消息b前發(fā)布膜蛔,則在所有Server上消息a都將在消息b前被發(fā)布;偏序是指如果一個(gè)消息b在消息a后被同一個(gè)發(fā)送者發(fā)布脖阵,a必將排在b前面
ZooKeeper典型使用場(chǎng)景一覽
ZooKeeper是一個(gè)高可用的分布式數(shù)據(jù)管理與系統(tǒng)協(xié)調(diào)框架皂股。基于對(duì)Paxos算法的實(shí)現(xiàn)命黔,使該框架保證了分布式環(huán)境中數(shù)據(jù)的強(qiáng)一致性呜呐,也正是基于這樣的特性就斤,使得zookeeper能夠應(yīng)用于很多場(chǎng)景。
數(shù)據(jù)發(fā)布與訂閱
發(fā)布與訂閱即所謂的配置管理蘑辑,顧名思義就是將數(shù)據(jù)發(fā)布到zk節(jié)點(diǎn)上洋机,供訂閱者動(dòng)態(tài)獲取數(shù)據(jù),實(shí)現(xiàn)配置信息的集中式管理和動(dòng)態(tài)更新洋魂。例如全局的配置信息绷旗,地址列表等就非常適合使用。
索引信息和集群中機(jī)器節(jié)點(diǎn)狀態(tài)存放在zk的一些指定節(jié)點(diǎn)副砍,供各個(gè)客戶端訂閱使用衔肢。
系統(tǒng)日志(經(jīng)過處理后的)存儲(chǔ),這些日志通常2-3天后被清除豁翎。
應(yīng)用中用到的一些配置信息集中管理角骤,在應(yīng)用啟動(dòng)的時(shí)候主動(dòng)來獲取一次,并且在節(jié)點(diǎn)上注冊(cè)一個(gè)Watcher心剥,以后每次配置有更新邦尊,實(shí)時(shí)通知到應(yīng)用,獲取最新配置信息刘陶。
業(yè)務(wù)邏輯中需要用到的一些全局變量胳赌,比如一些消息中間件的消息隊(duì)列通常有個(gè)offset,這個(gè)offset存放在zk上匙隔,這樣集群中每個(gè)發(fā)送者都能知道當(dāng)前的發(fā)送進(jìn)度疑苫。
系統(tǒng)中有些信息需要?jiǎng)討B(tài)獲取,并且還會(huì)存在人工手動(dòng)去修改這個(gè)信息纷责。以前通常是暴露出接口捍掺,例如JMX接口,有了zk后再膳,只要將這些信息存放到zk節(jié)點(diǎn)上即可挺勿。
分布通知/協(xié)調(diào)
ZooKeeper 中特有watcher注冊(cè)與異步通知機(jī)制,能夠很好的實(shí)現(xiàn)分布式環(huán)境下不同系統(tǒng)之間的通知與協(xié)調(diào)喂柒,實(shí)現(xiàn)對(duì)數(shù)據(jù)變更的實(shí)時(shí)處理不瓶。使用方法通常是不同系統(tǒng)都對(duì) ZK上同一個(gè)znode進(jìn)行注冊(cè),監(jiān)聽znode的變化(包括znode本身內(nèi)容及子節(jié)點(diǎn)的)灾杰,其中一個(gè)系統(tǒng)update了znode蚊丐,那么另一個(gè)系統(tǒng)能夠收到通知,并作出相應(yīng)處理艳吠。
另一種心跳檢測(cè)機(jī)制:檢測(cè)系統(tǒng)和被檢測(cè)系統(tǒng)之間并不直接關(guān)聯(lián)起來麦备,而是通過zk上某個(gè)節(jié)點(diǎn)關(guān)聯(lián),大大減少系統(tǒng)耦合。
另一種系統(tǒng)調(diào)度模式:某系統(tǒng)有控制臺(tái)和推送系統(tǒng)兩部分組成凛篙,控制臺(tái)的職責(zé)是控制推送系統(tǒng)進(jìn)行相應(yīng)的推送工作黍匾。管理人員在控制臺(tái)作的一些操作,實(shí)際上是修改了ZK上某些節(jié)點(diǎn)的狀態(tài)呛梆,而zk就把這些變化通知給他們注冊(cè)Watcher的客戶端锐涯,即推送系統(tǒng),于是填物,作出相應(yīng)的推送任務(wù)全庸。
另一種工作匯報(bào)模式:一些類似于任務(wù)分發(fā)系統(tǒng),子任務(wù)啟動(dòng)后融痛,到zk來注冊(cè)一個(gè)臨時(shí)節(jié)點(diǎn)壶笼,并且定時(shí)將自己的進(jìn)度進(jìn)行匯報(bào)(將進(jìn)度寫回這個(gè)臨時(shí)節(jié)點(diǎn)),這樣任務(wù)管理者就能夠?qū)崟r(shí)知道任務(wù)進(jìn)度雁刷。
總之覆劈,使用zookeeper來進(jìn)行分布式通知和協(xié)調(diào)能夠大大降低系統(tǒng)之間的耦合。
分布式鎖
分布式鎖沛励,這個(gè)主要得益于ZooKeeper為我們保證了數(shù)據(jù)的強(qiáng)一致性责语,即用戶只要完全相信每時(shí)每刻,zk集群中任意節(jié)點(diǎn)(一個(gè)zk server)上的相同znode的數(shù)據(jù)是一定是相同的目派。鎖服務(wù)可以分為兩類坤候,一個(gè)是保持獨(dú)占,另一個(gè)是控制時(shí)序企蹭。
保持獨(dú)占白筹,就是所有試圖來獲取這個(gè)鎖的客戶端,最終只有一個(gè)可以成功獲得這把鎖谅摄。通常的做法是把zk上的一個(gè)znode看作是一把鎖徒河,通過create znode的方式來實(shí)現(xiàn)。所有客戶端都去創(chuàng)建 /distribute_lock 節(jié)點(diǎn)送漠,最終成功創(chuàng)建的那個(gè)客戶端也即擁有了這把鎖顽照。
控制時(shí)序,就是所有視圖來獲取這個(gè)鎖的客戶端闽寡,最終都是會(huì)被安排執(zhí)行代兵,只是有個(gè)全局時(shí)序了。做法和上面基本類似爷狈,只是這里 /distribute_lock 已經(jīng)預(yù)先存在植影,客戶端在它下面創(chuàng)建臨時(shí)有序節(jié)點(diǎn)(這個(gè)可以通過節(jié)點(diǎn)的屬性控制:CreateMode.EPHEMERAL_SEQUENTIAL來指定)。Zk的父節(jié)點(diǎn)(/distribute_lock)維持一份sequence,保證子節(jié)點(diǎn)創(chuàng)建的時(shí)序性淆院,從而也形成了每個(gè)客戶端的全局時(shí)序何乎。
集群管理
集群機(jī)器監(jiān)控:這通常用于那種對(duì)集群中機(jī)器狀態(tài),機(jī)器在線率有較高要求的場(chǎng)景土辩,能夠快速對(duì)集群中機(jī)器變化作出響應(yīng)支救。這樣的場(chǎng)景中,往往有一個(gè)監(jiān)控系統(tǒng)拷淘,實(shí)時(shí)檢測(cè)集群機(jī)器是否存活各墨。過去的做法通常是:監(jiān)控系統(tǒng)通過某種手段(比如ping)定時(shí)檢測(cè)每個(gè)機(jī)器,或者每個(gè)機(jī)器自己定時(shí)向監(jiān)控系統(tǒng)匯報(bào)“我還活著”启涯。 這種做法可行贬堵,但是存在兩個(gè)比較明顯的問題:1. 集群中機(jī)器有變動(dòng)的時(shí)候,牽連修改的東西比較多结洼。2. 有一定的延時(shí)黎做。
利用ZooKeeper有兩個(gè)特性,就可以實(shí)時(shí)另一種集群機(jī)器存活性監(jiān)控系統(tǒng):a. 客戶端在節(jié)點(diǎn) x 上注冊(cè)一個(gè)Watcher松忍,那么如果 x 的子節(jié)點(diǎn)變化了蒸殿,會(huì)通知該客戶端。b. 創(chuàng)建EPHEMERAL類型的節(jié)點(diǎn)鸣峭,一旦客戶端和服務(wù)器的會(huì)話結(jié)束或過期宏所,那么該節(jié)點(diǎn)就會(huì)消失。Master選舉則是zookeeper中最為經(jīng)典的使用場(chǎng)景了摊溶。
在分布式環(huán)境中爬骤,相同的業(yè)務(wù)應(yīng)用分布在不同的機(jī)器上,有些業(yè)務(wù)邏輯(例如一些耗時(shí)的計(jì)算莫换,網(wǎng)絡(luò)I/O處理)霞玄,往往只需要讓整個(gè)集群中的某一臺(tái)機(jī)器進(jìn)行執(zhí)行, 其余機(jī)器可以共享這個(gè)結(jié)果拉岁,這樣可以大大減少重復(fù)勞動(dòng)溃列,提高性能,于是這個(gè)master選舉便是這種場(chǎng)景下的碰到的主要問題膛薛。利用ZooKeeper的強(qiáng)一致性听隐,能夠保證在分布式高并發(fā)情況下節(jié)點(diǎn)創(chuàng)建的全局唯一性,即:同時(shí)有多個(gè)客戶端請(qǐng)求創(chuàng)建 /currentMaster 節(jié)點(diǎn)哄啄,最終一定只有一個(gè)客戶端請(qǐng)求能夠創(chuàng)建成功雅任。