摘要:有可能是宕機(jī)或負(fù)荷嚴(yán)重的情況導(dǎo)致的。為分布式系統(tǒng)提供了協(xié)調(diào)功能和控制沖突。
背景
隨著計(jì)算機(jī)的硬件和操作系統(tǒng)兩者相輔相成地發(fā)展,從早期的ENIAC計(jì)算機(jī)到現(xiàn)在的x86的計(jì)算機(jī),從以前的單一控制終端(Single Operator, Single Console, SOSC)的操作系統(tǒng)到現(xiàn)在百花爭(zhēng)鳴的操作系統(tǒng)(如MacOS、Windows、Linux等),現(xiàn)代的操作系統(tǒng)發(fā)展還有一個(gè)最重要的特征是網(wǎng)絡(luò)的出現(xiàn),網(wǎng)絡(luò)促進(jìn)了網(wǎng)絡(luò)操作性系統(tǒng)和分布式操作系統(tǒng)的出現(xiàn)。對(duì)于網(wǎng)絡(luò)操作系統(tǒng)來(lái)說(shuō),其任務(wù)是將多個(gè)計(jì)算機(jī)虛擬成一個(gè)計(jì)算機(jī)。傳統(tǒng)的網(wǎng)絡(luò)操作系統(tǒng)是在現(xiàn)有操作系統(tǒng)的基礎(chǔ)上增加網(wǎng)絡(luò)功能,而分布式操作系統(tǒng)則是從一開(kāi)始就把對(duì)多計(jì)算機(jī)的支持考慮進(jìn)來(lái),是重新設(shè)計(jì)的操作系統(tǒng),所以比網(wǎng)絡(luò)操作系統(tǒng)效率高。分布式操作系統(tǒng)除了提供傳統(tǒng)操作系統(tǒng)的功能外,還提供多計(jì)算機(jī)協(xié)作的功能。
根據(jù)上述的發(fā)展,我們?cè)谄浠A(chǔ)上構(gòu)建的應(yīng)用也分為集中式系統(tǒng)和分布式系統(tǒng)。集中式系統(tǒng)具有明顯的單點(diǎn)問(wèn)題。大型主機(jī)雖然在性能和穩(wěn)定性方面表現(xiàn)卓越,但這不代表它永遠(yuǎn)不會(huì)出問(wèn)題。另外隨著業(yè)務(wù)的不斷發(fā)展,用戶訪問(wèn)迅速提高,計(jì)算機(jī)系統(tǒng)的規(guī)模也在不斷擴(kuò)大,在單一大型主機(jī)上進(jìn)行的系統(tǒng)的擴(kuò)容往往比較困難。
按照正常的套路來(lái)說(shuō),下一步應(yīng)該是說(shuō)隨著PC的性能不斷提升和網(wǎng)絡(luò)技術(shù)的快速普及,所以很多企業(yè)就開(kāi)始去掉大型機(jī),從而改用普通PC來(lái)作為分布式的計(jì)算機(jī)系統(tǒng)。這樣說(shuō)就太平淡了,企業(yè)也不是這么容易說(shuō)變就變,就算谷歌開(kāi)始的時(shí)候敢用可靠性較低的服務(wù)器的一個(gè)重要原因,在于它是最初并不為用戶提供存儲(chǔ)和計(jì)算服務(wù),服務(wù)器都是自己內(nèi)部使用。如果計(jì)算到一半死機(jī)了,那就再?gòu)乃罊C(jī)的斷點(diǎn)重新啟動(dòng)計(jì)算。甚至如果一開(kāi)始有些中間數(shù)據(jù)丟失了,那就再產(chǎn)生一遍。這時(shí)它的可靠性不像銀行那樣重要。2004年當(dāng)谷歌開(kāi)始提供Gmail服務(wù),為了確保用戶的數(shù)據(jù)不丟失,它采用了3x3九臺(tái)服務(wù)器存一組數(shù)據(jù),這個(gè)成本就不低了。同時(shí)期,雅虎等公司采用兩臺(tái)可靠性的服務(wù)器存儲(chǔ)郵件。這時(shí)期,谷歌的Gmail是非常賠錢(qián)的。后來(lái)谷歌的云存儲(chǔ)部門(mén)用軟件實(shí)現(xiàn)了5臺(tái)服務(wù)器分布式存儲(chǔ),達(dá)到過(guò)去九臺(tái)服務(wù)器的可靠性,Gmail的成本才降下來(lái)。谷歌想方設(shè)法用廉價(jià)服務(wù)器集群取代超級(jí)計(jì)算機(jī)的過(guò)程遠(yuǎn)比很多人想象的復(fù)雜。這種想法其實(shí)早在谷歌之前就有了,但是其它公司就是因?yàn)闊o(wú)法解決其中的很多技術(shù)細(xì)節(jié)問(wèn)題,使得采用大量低可靠性的服務(wù)器帶來(lái)的好處還沒(méi)有它帶來(lái)的麻煩多,最終都放棄了。(這里引申出谷歌的文化之一)谷歌把事做到了極致,克服了各種技術(shù)困難,最后做成了。
企業(yè)吸收已證實(shí)可行的經(jīng)驗(yàn)是很快速,于是后來(lái)亞馬遜等公司也實(shí)現(xiàn)了廉價(jià)服務(wù)器集群取代超級(jí)計(jì)算機(jī)的功能。其中在國(guó)內(nèi),最為典型的就是阿里巴巴的“去IOE”活動(dòng),
也正是在這個(gè)大背景之下,還有在大數(shù)據(jù)和云計(jì)算驅(qū)動(dòng)之下,ZooKeeper在雅虎里誕生了。用于解決很多分布式系統(tǒng)下的問(wèn)題。當(dāng)設(shè)計(jì)一個(gè)使用ZooKeeper的應(yīng)用時(shí),最好就是將應(yīng)用數(shù)據(jù)和協(xié)調(diào)數(shù)據(jù)給分開(kāi)。如郵件系統(tǒng),用戶只關(guān)心他們的郵箱內(nèi)容,而不需要知道哪臺(tái)郵箱服務(wù)器在處理。因此在這里郵箱內(nèi)容就是應(yīng)用數(shù)據(jù),而協(xié)調(diào)數(shù)據(jù)則是具體是哪臺(tái)郵件服務(wù)器在處理。
分布式的問(wèn)題由于分布式系統(tǒng)概念有很多種,在這里我們定義為:一個(gè)系統(tǒng)由多個(gè)組件組成,而每個(gè)組件獨(dú)立并同時(shí)運(yùn)行在不同的物理機(jī)器上。
分布式系統(tǒng)一誕生就面臨諸多的難題和挑戰(zhàn)。典型的問(wèn)題有這些:
通信失敗(Communication Failure)
由于分布系統(tǒng)引入了網(wǎng)絡(luò)因素,而網(wǎng)絡(luò)本身是不穩(wěn)定的。因此分布式系統(tǒng)中各個(gè)結(jié)點(diǎn)之前進(jìn)網(wǎng)絡(luò)通信時(shí),會(huì)出現(xiàn)消息丟失和消息延遲等現(xiàn)象。
網(wǎng)絡(luò)分區(qū)(Network Partion)
網(wǎng)絡(luò)分區(qū),也稱(chēng)腦裂(split-brain),集群中部分節(jié)點(diǎn)之間不可達(dá)而引起的(或者因?yàn)楣?jié)點(diǎn)請(qǐng)求壓力較大,導(dǎo)致其他節(jié)點(diǎn)與該節(jié)點(diǎn)的心跳檢測(cè)不可用)。當(dāng)上述情況發(fā)生時(shí),不同分裂的小集群會(huì)自主的選擇出master節(jié)點(diǎn),造成原本的集群會(huì)同時(shí)存在多個(gè)master節(jié)點(diǎn)。
三態(tài)
因?yàn)橥ㄐ攀〉膯?wèn)題,會(huì)帶來(lái)其中一個(gè)問(wèn)題是三態(tài),三態(tài)即成功、失敗與超時(shí)。分布式系統(tǒng)的每一次請(qǐng)求與響應(yīng)都會(huì)有這三種結(jié)果。最麻煩的是超時(shí),因?yàn)樗嬖谶@兩種可能:
1.由于通訊失敗,該請(qǐng)求(消息)并沒(méi)有被成功地發(fā)送到接收方,而是在發(fā)送過(guò)程中就丟失了。
2.該請(qǐng)求(消息)成功地被接收方接收后,并進(jìn)行了處理,但是在將響應(yīng)反饋給發(fā)送方時(shí),發(fā)生了消息丟失現(xiàn)象。
節(jié)點(diǎn)故障
這也是屬于通信失敗的情況,但著重點(diǎn)是說(shuō),機(jī)器自身掛了,無(wú)法發(fā)出消息。有可能是宕機(jī)或負(fù)荷嚴(yán)重的情況導(dǎo)致的。
上述分布式問(wèn)題導(dǎo)致了一致性問(wèn)題難以解決,而且在2002年的時(shí)候,MIT的Seth Gibert和Nancy Lynch證明的CAP定理。這個(gè)定理是:系統(tǒng)不可能同時(shí)滿足一致性(Consistency)、可用性(Availability)和分區(qū)容錯(cuò)性(Partition tolerance)。
既然是邏輯證明出來(lái)的,那它就一定對(duì)的。這也是分布式系統(tǒng)的邊界或者說(shuō)是上限。所以人們開(kāi)始在一致性和可用性上權(quán)衡,從而誕生很多算法如2PC、3PC和Paxos算法,這些都影響著ZooKeeper的設(shè)計(jì)。
ZooKeeper不能解決所有分布式系統(tǒng)的問(wèn)題。但它提供了一個(gè)很好框架去處理這些問(wèn)題。
ZooKeeper為分布式系統(tǒng)提供了協(xié)調(diào)功能和控制沖突。協(xié)調(diào)意思是說(shuō)幾個(gè)進(jìn)程需要一起做一些事情,例如,在Master-Worker分布式架構(gòu)里,worker通知master它可用,master因此分派任務(wù)給它。
而控制沖突則不一樣:它更多是這種情形,兩個(gè)進(jìn)程是不能同時(shí)進(jìn)行,一個(gè)必須等待一個(gè)才能進(jìn)行。例如,在Master-Worker分布式架構(gòu)里,我們希望只有一個(gè)進(jìn)程變成master,所以當(dāng)多個(gè)進(jìn)程同時(shí)激活自己為master時(shí),必須實(shí)現(xiàn)互斥( mutual exclusion),只能有一個(gè)進(jìn)程獲得鎖,并成為master角色。
ZooKeeper的API提供了:
強(qiáng)一致性,順序和持久化的保證
提供實(shí)現(xiàn)同步的能力
一個(gè)更簡(jiǎn)單的方法處理分布式系統(tǒng)中的并發(fā)問(wèn)題。
ZooKeeper的基礎(chǔ)我們將圍繞一個(gè)例子去講述概念并實(shí)踐。這個(gè)例子是:Master-Worker分布式架構(gòu)。
架構(gòu)圖如下:
Master進(jìn)程的職責(zé)時(shí)跟蹤Worker和任務(wù),并將任務(wù)分派給Worker。為了實(shí)現(xiàn)這個(gè)Master-Worker系統(tǒng),我們必須解決這三個(gè)關(guān)鍵問(wèn)題:
Master故障
如果master故障并且變得不可用,系統(tǒng)就不能分配新任務(wù)或重新分配失敗的任務(wù)。
Woker故障
如果worker故障,則分配給它的任務(wù)則完成不了。
通信失敗
如果master和worker不能交換信息,則worker可能無(wú)法獲取分派給它的任務(wù)。
為了解決上述問(wèn)題,這個(gè)系統(tǒng)必須有以下功能:能在一個(gè)master掛掉之后,重新選擇一個(gè)新的master;判斷那些woker是可用的;當(dāng)worker與master因?yàn)榫W(wǎng)絡(luò)分區(qū)失去與master連接時(shí)能夠重新分派任務(wù);當(dāng)一個(gè)節(jié)點(diǎn)獲得鎖之后發(fā)生網(wǎng)絡(luò)分區(qū)或掛掉時(shí),需讓這個(gè)鎖失效。
重新分配任務(wù)有以下情況:如果任務(wù)可重復(fù)執(zhí)行,則可以無(wú)需任何校驗(yàn)的把這任務(wù)重新分派。但如果這個(gè)任務(wù)是不能重復(fù)執(zhí)行的,則需要協(xié)調(diào)多個(gè)worker執(zhí)行任務(wù)的情況。znode
ZooKeeper并沒(méi)有直接提供上述的功能,而是提供一個(gè)跟文件系統(tǒng)很像的API。這個(gè)被組織稱(chēng)樹(shù)結(jié)構(gòu),每個(gè)結(jié)點(diǎn)都存儲(chǔ)很小的數(shù)據(jù)的結(jié)點(diǎn)(不超過(guò)1M),被稱(chēng)為znode。如下圖,根結(jié)點(diǎn)包含4個(gè)結(jié)點(diǎn),其中3個(gè)又是分支結(jié)點(diǎn),擁有葉子節(jié)點(diǎn)。而葉子結(jié)點(diǎn)就包含數(shù)據(jù)。
不存在的結(jié)點(diǎn)在znode里也是蘊(yùn)含信息。如在這個(gè)Master-Worker例子里,如果master結(jié)點(diǎn)不存在,則表明master還沒(méi)選出來(lái)。另外根據(jù)上圖,我們可以看出/workers結(jié)點(diǎn)是當(dāng)前系統(tǒng)中所有可用的woker的父節(jié)點(diǎn)。foo.com:2181是worker的信息。如果woker不可用了,就應(yīng)該把對(duì)于的結(jié)點(diǎn)從/worers上刪除。
而/tasks結(jié)點(diǎn)是父結(jié)點(diǎn),其子結(jié)點(diǎn)是已經(jīng)被創(chuàng)建的任務(wù),且等待被執(zhí)行。Master-Worker例子里,客戶端就可以在/tasks下創(chuàng)建一個(gè)結(jié)點(diǎn)來(lái)代表一個(gè)新任務(wù),并且等待該任務(wù)的狀態(tài)。
最后/assign結(jié)點(diǎn)的子結(jié)點(diǎn)是所有已經(jīng)被分派給worker的任務(wù)。
znode可以有和可以沒(méi)有數(shù)據(jù)。如果有數(shù)據(jù),數(shù)據(jù)類(lèi)型必須是字節(jié)數(shù)據(jù)(Byte Array)。字節(jié)數(shù)組的含義解釋就需要各自應(yīng)用決定,ZooKeeper沒(méi)有提供解析這字節(jié)數(shù)組的功能。
ZooKeeper的命令行提供了一下API:
create /path data
創(chuàng)建一個(gè)znode結(jié)點(diǎn)名為/path,包含數(shù)據(jù)data
delete /path
刪除znode結(jié)點(diǎn)/path
exists /path
檢查是否有/path結(jié)點(diǎn)
setData /path data
設(shè)置/path結(jié)點(diǎn)的數(shù)據(jù)
getData /path
獲取/path結(jié)點(diǎn)數(shù)據(jù)
getChildren /path
獲取/path結(jié)點(diǎn)的子結(jié)點(diǎn)列表
znode的模式在創(chuàng)建znode結(jié)點(diǎn)時(shí),我們可以指定模式(mode),不同模式?jīng)Q定znode結(jié)點(diǎn)的不同行為:
永久(Persistent)和臨時(shí)(Ephemeral)znode結(jié)點(diǎn)znode結(jié)點(diǎn)只能是永久結(jié)點(diǎn)或者是臨時(shí)結(jié)點(diǎn)。永久結(jié)點(diǎn)/path只能被delete命令刪除。而臨時(shí)結(jié)點(diǎn),在創(chuàng)建該結(jié)點(diǎn)的客戶端故障了或失去與ZooKeeper失去連接時(shí),這個(gè)結(jié)點(diǎn)會(huì)被刪除。
在Master-Worker例子里,我們需要維護(hù)任務(wù)的分派情況,哪怕master故障了。
臨時(shí)znode結(jié)點(diǎn)傳遞著這樣的信息:結(jié)點(diǎn)的創(chuàng)建者的session有效,則結(jié)點(diǎn)的應(yīng)用才能存在。例如,master的結(jié)點(diǎn)在Master-Worker例子里就是臨時(shí)的。master故障時(shí),master結(jié)點(diǎn)也不應(yīng)該存在。同樣的也適合worker的情況。
因?yàn)榕R時(shí)znode結(jié)點(diǎn)在它的創(chuàng)建者的session超時(shí)失效時(shí)被刪除,則我們不允許臨時(shí)結(jié)點(diǎn)擁有子結(jié)點(diǎn)。
一個(gè)znode可以被設(shè)置為序列(sequential)。一個(gè)序列結(jié)點(diǎn)時(shí)唯一的,單調(diào)遞增的整數(shù)。是在path后面追加序列數(shù)據(jù)。例如,如果一個(gè)客戶端創(chuàng)建一個(gè)序列znode結(jié)點(diǎn)/task/task-,ZooKeeper會(huì)分配一個(gè)序列,如1,追加到路徑上,則為/task/task-1。序列znode結(jié)點(diǎn)提供一個(gè)簡(jiǎn)便地方法去創(chuàng)建擁有唯一名字的znode結(jié)點(diǎn)。也可以被用來(lái)查看創(chuàng)建znode結(jié)點(diǎn)的順序。
總結(jié)因此總的來(lái)說(shuō),znode有以下四個(gè)模式:persistent, ephemeral, persistent_sequential和ephemeral_sequential。
Watch與通知(Watches and Notifications)由于是遠(yuǎn)程訪問(wèn)ZooKeeper,所以訪問(wèn)znode結(jié)點(diǎn)是非常昂貴的:高延遲或多無(wú)用的操作??紤]以下情況,如果下圖,第二次使用getChildren /task返回的是同樣的值,因此時(shí)沒(méi)有必要的。
這是輪訓(xùn)(polling)的普遍出現(xiàn)的問(wèn)題。我們使用一種叫通知(notifications)的機(jī)制來(lái)代理客戶端的輪訓(xùn):客戶端在ZooKeeper上注冊(cè)接收znode結(jié)點(diǎn)變化的通知。指定一個(gè)znode結(jié)點(diǎn),接受其一個(gè)通知的注冊(cè),這過(guò)程叫 設(shè)置watch。一個(gè)watch是單步操作(one-shot operation),也就是說(shuō)一個(gè)watch僅僅觸發(fā)一個(gè)通知。如果想接受多個(gè)通知,則需要在接受到通知后,重新設(shè)置watch。設(shè)置watch和接受通知的過(guò)程如下圖:
版本(Version)每一個(gè)znode結(jié)點(diǎn)都會(huì)有一個(gè)版本號(hào),這個(gè)版本號(hào)在每次結(jié)點(diǎn)的數(shù)據(jù)發(fā)生改變都會(huì)遞增。這樣ZooKeeper的一些API操作就可以帶上條件,這操作如setData和Delete。設(shè)置數(shù)據(jù)時(shí)可以帶上版本號(hào),版本號(hào)匹配不上則操作失敗。操作過(guò)程如下圖:
ZooKeeper的架構(gòu)客戶端可以通過(guò)client庫(kù)來(lái)與ZooKeeper節(jié)點(diǎn)進(jìn)行通信。
ZooKeeper服務(wù)可以有兩種模式:?jiǎn)螜C(jī)(standalone)和法定人數(shù)(quorum)。單機(jī)模式也就是單個(gè)服務(wù)器,ZooKeeper的狀態(tài)不會(huì)被復(fù)制(replicate)。而在法定人數(shù)模式下,則會(huì)有一組ZooKeeper服務(wù)器,也稱(chēng)為ZooKeeper套裝(ZooKeeper ensemble),節(jié)點(diǎn)之間會(huì)復(fù)制ZooKeeper的狀態(tài),并一起提供服務(wù)。
在法定人數(shù)模式下,ZooKeeper會(huì)冗余(replicate)它的數(shù)據(jù)到各個(gè)服務(wù)器里。當(dāng)如果客戶端必須等待每個(gè)服務(wù)器都保持好它的數(shù)據(jù),才能往下進(jìn)行操作,則延遲將會(huì)難以接受。在現(xiàn)實(shí)世界的公共事務(wù)管理里,法定人數(shù)是要求出席投票的最低人數(shù)。而在ZooKeeper里,法定人數(shù)是保證ZooKeeper能夠正常工作,可用,的最少服務(wù)器數(shù)量。這個(gè)最少數(shù)量也是保證至少有這么多臺(tái)服務(wù)器是同步了數(shù)據(jù)的。這樣才能保證數(shù)據(jù)是被安全保存。如我們用5臺(tái)ZooKeeper服務(wù)器,則法定人數(shù)則為3臺(tái)。只要有3臺(tái)服務(wù)器保存了數(shù)據(jù),客戶端則可以往下繼續(xù)自己的事情,另外兩天服務(wù)器最終會(huì)同步剛剛保存的數(shù)據(jù)。
會(huì)話(Session)客戶端在對(duì)ZooKeeper發(fā)送任何請(qǐng)求之前,都得先與ZooKeeper建立會(huì)話(session)。會(huì)話這個(gè)概念在ZooKeeper里是非常重要且關(guān)鍵的。所有操作都必須關(guān)聯(lián)著會(huì)話。當(dāng)一個(gè)會(huì)話因?yàn)槟承┰蚪Y(jié)束時(shí),通過(guò)這會(huì)話創(chuàng)建的臨時(shí)結(jié)點(diǎn)也將會(huì)伴隨這會(huì)話的結(jié)束而被刪除。
客戶端是通過(guò)TCP連接來(lái)與服務(wù)器通信,客戶端只能連接一個(gè)服務(wù)器。如果客戶端連接的一臺(tái)服務(wù)器掛了,則session將會(huì)移動(dòng)到下一臺(tái)服務(wù)器,這個(gè)移動(dòng)過(guò)程是透明的,由ZooKeeper負(fù)責(zé)處理的。
會(huì)話提供了有序保證(order guarantees),意思是一個(gè)會(huì)話里的操作都是FIFO的順序。但跨session操作時(shí),哪怕session不是重疊,而是連續(xù)的不同的session,這個(gè)FIFO的順序也會(huì)被破壞,如:
客戶端建立一個(gè)session,并異步的連續(xù)的發(fā)送兩個(gè)操作,create /tasks和/workers.
第一個(gè)session失效
客戶端建立其他session,也發(fā)送一個(gè)異步請(qǐng)求,create /assign
在這種情況下,是有可能僅僅只有/tasks和/assign被創(chuàng)建,/workers而沒(méi)有被創(chuàng)建。這是因?yàn)楸唤诲e(cuò)的會(huì)話給打斷了。
ZooKeeper的命令行體驗(yàn)通過(guò)命令行來(lái)操作ZooKeeper來(lái)實(shí)現(xiàn)Master-Worker這個(gè)例子。
安裝ZooKeeper(quorum模式)1.下載安裝包zookeeper-3.4.5.tar.gz
2.解壓zookeeper-3.4.5.tar.gz到/usr/local
tar -zxvf zookeeper-3.4.5.tar.gz
3.創(chuàng)建zoo.cfg配置文件
mv conf/zoo_sample.cfg conf/zoo.cfg
4.修改zoo.cfg配置文件,修改如下
#防止把根分區(qū)給被占滿 dataDir=/usr/local/zookeeper-3.4.5/tmp clientPort=2181 server.1=zk1.jevoncode.com:2888:3888 server.2=zk2.jevoncode.com:2888:3888 server.3=zk3.jevoncode.com:2888:3888
其中2181是ZooKeeper服務(wù)器的開(kāi)放給客戶端訪問(wèn)的端口,而2888和3888是ZooKeeper節(jié)點(diǎn)之間用于通信和leader選舉。
5.在各個(gè)結(jié)點(diǎn)的/usr/local/zookeeper-3.4.5/tmp目錄下建立myid文件,內(nèi)容為server的id,如給zk1.jevoncode.com這個(gè)結(jié)點(diǎn)添加myid
echo "1">/usr/local/zookeeper-3.4.5/tmp/myid
6.在每個(gè)結(jié)點(diǎn)啟動(dòng)ZooKeeper服務(wù)
./bin/zkServer.sh start
7.查看每個(gè)結(jié)點(diǎn)的狀態(tài),就可以看到leader和follower了
./bin/zkServer.sh status實(shí)現(xiàn)Master-Worker這個(gè)例子
我們通過(guò)zkCli.sh工具來(lái)實(shí)現(xiàn)Master-Worker這個(gè)例子的功能。
Master-Worker這個(gè)例子涉及到三個(gè)角色:
Master
這個(gè)master負(fù)責(zé)監(jiān)控新woker和任務(wù),并分派任務(wù)給可用的worker。
Worker
worker將自己注冊(cè)到該系統(tǒng)中,并保證master能夠看到它是可用的,可執(zhí)行任務(wù),然后監(jiān)聽(tīng)新任務(wù)。Master角色
客戶端
客戶端創(chuàng)建新任務(wù)并等待系統(tǒng)的響應(yīng)
1.在窗口A連接ZooKeeper
./bin/zkCli.sh -server zk1.jevoncode:2181,zk2.jevoncode:2181,zk3.jevoncode:2181
2.在窗口A創(chuàng)建臨時(shí)znode結(jié)點(diǎn)/master
create -e /master "master1.jevoncode.com:2223"
3.在窗口B連接ZooKeeper
./bin/zkCli.sh -server zk1.jevoncode:2181,zk2.jevoncode:2181,zk3.jevoncode:2181
4.在窗口B創(chuàng)建臨時(shí)znode結(jié)點(diǎn)/master,模擬兩個(gè)進(jìn)程激活master角色。這個(gè)會(huì)失敗
#會(huì)返回Node already exists: /master create -e /master "master2.jevoncode.com:2223"
5.在窗口B,既然/master已存在,則需監(jiān)聽(tīng)/master,以便當(dāng)窗口A的master故障時(shí),能快速恢復(fù)過(guò)來(lái)。stat命令是獲取znode屬性,然后后續(xù)參數(shù)true是設(shè)置一個(gè)watch在/master上
stat /master true
6.當(dāng)窗口A退出時(shí),窗口B會(huì)收到一下通知:
WatchedEvent state:SyncConnected type:NodeDeleted path:/master
7.此時(shí)窗口B就可以激活自己稱(chēng)為master
create -e /master "master2.jevoncode.com:2223"Worker角色、任務(wù)和任務(wù)分派
在繼續(xù)客戶端和Worker操作之前,我們需要?jiǎng)?chuàng)建三個(gè)父節(jié)點(diǎn),/workers, /tasks和/assign
create /workers "" create /tasks "" create /assign "" ls /
另外Master角色需監(jiān)聽(tīng)worker和任務(wù)
ls /workers true ls /tasks trueWorker角色
1.在窗口C連接ZooKeeper
./bin/zkCli.sh -server zk1.jevoncode:2181,zk2.jevoncode:2181,zk3.jevoncode:2181
2.創(chuàng)建一個(gè)worker結(jié)點(diǎn)
create -e /workers/worker1.jevoncode.com "worker1.jevoncode.com:2224"
3.此時(shí)Master角色的窗口會(huì)受到通知
WATCHER:: WatchedEvent state:SyncConnected type:NodeChildrenChanged path:/workers
4.worker需創(chuàng)建一個(gè)父節(jié)點(diǎn)來(lái)接受任務(wù)分派,并watch
create /assign/worker1.jevoncode.com "" ls /assign/worker1.jevoncode.com true客戶端角色
1.在窗口D連接ZooKeeper
./bin/zkCli.sh -server zk1.jevoncode:2181,zk2.jevoncode:2181,zk3.jevoncode:2181
2.提交任務(wù),在這里是創(chuàng)建一個(gè)序列znode結(jié)點(diǎn)。
create -s /tasks/task- "cmd"
3.設(shè)置一個(gè)watch,等待任務(wù)完成
ls /task/task-0000000000 true
4.當(dāng)任務(wù)創(chuàng)建是,Master的窗口將會(huì)收到通知
WATCHER:: WatchedEvent state:SyncConnected type:NodeChildrenChanged path:/tasks
5.此時(shí)Master窗口查看任務(wù),查看可用worker并分派任務(wù)
ls /tasks ls /workers create /assign/worker1.jevoncode.com/task-0000000000 ""
6.此時(shí)Worker窗口C收到通知
WATCHER:: WatchedEvent state:SyncConnected type:NodeChildrenChanged path:/assign/worker1.example.com
7.Worker窗口C,查看任務(wù),并執(zhí)行完任務(wù)后修改任務(wù)狀態(tài)
ls /assign/worker1.jevoncode.com create /tasks/task-0000000000/status "done"
8.客戶端收到通知,并查看任務(wù)完成結(jié)果
#通知 WATCHER:: WatchedEvent state:SyncConnected type:NodeChildrenChanged path:/tasks/task-0000000000 #查看結(jié)果 get /tasks/task-0000000000
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/69195.html
閱讀 856·2023-04-25 22:57
閱讀 3083·2021-11-23 10:03
閱讀 649·2021-11-22 15:24
閱讀 3190·2021-11-02 14:47
閱讀 2940·2021-09-10 11:23
閱讀 3155·2021-09-06 15:00
閱讀 3984·2019-08-30 15:56
閱讀 3358·2019-08-30 15:52