zookeeper分布式過(guò)程協(xié)同技術(shù)詳解

上來(lái)就送干貨? 本書(shū)的練習(xí)以及代碼可以再O’Reilly官網(wǎng)網(wǎng)站本書(shū)頁(yè)面下載恩商。

相關(guān)鏈接

http://www.oreilly.com.cn

http://www.oreilly.com

1、區(qū)分,單機(jī)多線程和分布式多線程的區(qū)別

在典型的不共享環(huán)境下不同的計(jì)算機(jī)之間不共享除網(wǎng)絡(luò)之外的其他任何信息,言外之意豪诲,就是它們之間能夠溝通的方式只有網(wǎng)絡(luò)榆芦。

2、zookeeper在分布式環(huán)境下的作用:

利用消息傳遞算法實(shí)現(xiàn)同步原語(yǔ)耕蝉,zookeeper提供某種有序共享存儲(chǔ)的組件。

Apache kafka ?利用zookeeper檢測(cè)崩潰夜只,實(shí)現(xiàn)主題的發(fā)現(xiàn)垒在,并發(fā)癡主題的生產(chǎn)和消費(fèi)

Apache Solr ?是一起企業(yè)級(jí)的搜索平臺(tái)。使用ZooKeeper來(lái)存儲(chǔ)集群的元數(shù)據(jù)扔亥,并協(xié)作更新這些元數(shù)據(jù)场躯。

Yahoo!Fetching Service 是爬蟲(chóng)實(shí)現(xiàn)的一部分旅挤,通過(guò)緩存內(nèi)容的方法高效地獲取網(wǎng)頁(yè)信息踢关,同時(shí)確保滿(mǎn)足網(wǎng)頁(yè)服務(wù)器的管理規(guī)則。該服務(wù)器采用zookeeper實(shí)現(xiàn)主節(jié)點(diǎn)的選舉粘茄、奔潰檢測(cè)和元數(shù)據(jù)的存儲(chǔ)签舞。

zookeeper的客戶(hù)端API的強(qiáng)大:

1、保障強(qiáng)一致性柒瓣、有序性和持久性儒搭。

2、實(shí)現(xiàn)通過(guò)的同步原語(yǔ)能力

3芙贫、在實(shí)際的分布式系統(tǒng)中搂鲫,并發(fā)往往導(dǎo)致不正確的行為。ZooKeeper提供了一種簡(jiǎn)單的并發(fā)處理機(jī)制

對(duì)于一致性和持久性的不同需求磺平,最佳時(shí)間還是應(yīng)該講應(yīng)用數(shù)據(jù)和協(xié)同數(shù)據(jù)獨(dú)立開(kāi)魂仍。

1.1.2 ZooKeeper不適用的場(chǎng)景,ZooKeeper不適合用作海量數(shù)據(jù)存儲(chǔ)拣挪,取而代之的可以采用數(shù)據(jù)庫(kù)或者分布式文件系統(tǒng)等擦酌,

分布式系統(tǒng)中的進(jìn)程通訊有兩種選擇:直接通過(guò)網(wǎng)絡(luò)進(jìn)行信息交換,或讀取某些共享的存儲(chǔ)菠劝。ZooKeeper使用的共享存儲(chǔ)模型來(lái)使用應(yīng)用間協(xié)作和同步原語(yǔ)赊舶。對(duì)于共享存儲(chǔ)本身,有需要在進(jìn)程和存儲(chǔ)間進(jìn)行網(wǎng)絡(luò)通訊。網(wǎng)絡(luò)是分布式系統(tǒng)中并行設(shè)計(jì)的基礎(chǔ)锯岖。

備份主節(jié)點(diǎn)卻認(rèn)為主節(jié)點(diǎn)已經(jīng)奔潰,例如節(jié)點(diǎn)負(fù)載很高甫何,導(dǎo)致消息延遲出吹,備份主節(jié)點(diǎn)將接管成功主節(jié)點(diǎn)的角色,執(zhí)行所有必要的程序辙喂,如果一些從節(jié)點(diǎn)無(wú)法與主要主節(jié)點(diǎn)的通信捶牢,如由于網(wǎng)絡(luò)分區(qū)(network partition)錯(cuò)誤導(dǎo)致。針對(duì)這個(gè)場(chǎng)景中導(dǎo)致的問(wèn)題巍耗,我們一般稱(chēng)之為腦裂(split-brain):系統(tǒng)中兩個(gè)獲得多個(gè)部分開(kāi)始獨(dú)立工作秋麸,導(dǎo)致整體行為不一致性。

1.2.3 通信故障

如果一個(gè)從節(jié)點(diǎn)與主節(jié)點(diǎn)的網(wǎng)絡(luò)連接斷開(kāi)炬太,比如網(wǎng)絡(luò)分區(qū)(network partition)導(dǎo)致灸蟆,重新分配一個(gè)任務(wù),可能會(huì)導(dǎo)致兩個(gè)從節(jié)點(diǎn)執(zhí)行相同的任務(wù)亲族。

元數(shù)據(jù):主節(jié)點(diǎn)和從節(jié)點(diǎn)必須具有通過(guò)某種可靠的方式來(lái)保存分配狀態(tài)和執(zhí)行狀態(tài)的能力

1.3分布式協(xié)作的難點(diǎn)

當(dāng)開(kāi)發(fā)分布式應(yīng)用時(shí)炒考,其復(fù)雜性會(huì)立即凸顯出來(lái),例如霎迫,當(dāng)我們的應(yīng)用啟動(dòng)后斋枢,所有不同的進(jìn)程通過(guò)某種方式,需要知道應(yīng)用的配置信息知给,一段時(shí)間之后瓤帚,配置信息也許發(fā)生了很大的變化,我們可以停止所有的進(jìn)程涩赢,重新分發(fā)配置信息的文件戈次,然后重新啟動(dòng),但是重新匹配就會(huì)延長(zhǎng)應(yīng)用的停機(jī)時(shí)間筒扒。

FLP(Fischer Lynch Patternson)這個(gè)結(jié)論證明了在異步通信的分布式系統(tǒng)中朝扼,進(jìn)程奔潰,所有的進(jìn)程可能無(wú)法在這個(gè)比特位的配置上達(dá)成一致霎肯。類(lèi)似定律稱(chēng)為CAP ?表示一致性(Consistency)擎颖,可用性(Avaliability)和分區(qū)容錯(cuò)性(Partition-tolerance),該定力指出观游,當(dāng)設(shè)計(jì)一個(gè)分布式系統(tǒng)時(shí)搂捧,我們希望這種屬性全部滿(mǎn)足,但沒(méi)有系統(tǒng)可以同時(shí)滿(mǎn)足這三種屬性懂缕。因此ZooKeeper的設(shè)計(jì)盡可能滿(mǎn)足一致性和可用性允跑,當(dāng)然,發(fā)生網(wǎng)絡(luò)分區(qū)時(shí)也提高了只讀能力。

我們無(wú)法擁有一個(gè)理想的故障容錯(cuò)聋丝、分布式的索烹、真是的環(huán)境存在的系統(tǒng)來(lái)處理所發(fā)生的所有的問(wèn)題,

適當(dāng)放款目標(biāo):假設(shè)時(shí)鐘在某種范圍內(nèi)是同步的弱睦,大媽也可以犧牲一些網(wǎng)絡(luò)分區(qū)容錯(cuò)的能力百姓,并認(rèn)為其一直是一致的。

1.4 ZooKeeper的成功和注意事項(xiàng)

Paxos算法和虛擬同步技術(shù)Virtual Synchrony况木,通過(guò)這些技術(shù)可以無(wú)縫的處理所發(fā)生的某些變化或情況垒拢,并提供一個(gè)開(kāi)發(fā)者一框架。

2.1 zookeeper基礎(chǔ)

提供元語(yǔ)列表火惊,暴露出每個(gè)原語(yǔ)的實(shí)例化調(diào)用方法求类,并直接控制這些實(shí)例。

比如:分布式鎖機(jī)制組成了一個(gè)重要的原語(yǔ)屹耐,同時(shí)暴露創(chuàng)建create 獲取acquire 和釋放release三個(gè)調(diào)用方法

這種設(shè)計(jì)存在一個(gè)重大的缺陷:首先尸疆,我們要么預(yù)先提出一份詳盡的原語(yǔ)的列表,要么提供API的擴(kuò)展惶岭,以便引入新的原語(yǔ)仓技;其次以這種方式實(shí)現(xiàn)元語(yǔ)的服務(wù)是的應(yīng)用上市了靈活性。

因此在zookeeper中俗他,我們另辟蹊徑脖捻。zookeeper并不直接暴露原語(yǔ),取而代之兆衅,它暴露了由一小部分調(diào)用方法組成的類(lèi)似文件系統(tǒng)的API地沮,以便允許應(yīng)用實(shí)現(xiàn)自己的原語(yǔ)。我們通常使用菜譜(recipes)來(lái)表示這些原語(yǔ)羡亩。菜譜包括zookeeper操作和維護(hù)的一個(gè)小型的數(shù)據(jù)節(jié)點(diǎn)摩疑,這些數(shù)據(jù)節(jié)點(diǎn)被稱(chēng)為znode,采用類(lèi)似于文件系統(tǒng)的層級(jí)樹(shù)狀結(jié)構(gòu)進(jìn)行管理畏铆。




2.1.1 API概述

znode 節(jié)點(diǎn)可能還有數(shù)據(jù)雷袋,也可能沒(méi)有,如果一個(gè)znode節(jié)點(diǎn)包含任何數(shù)據(jù)辞居,那么數(shù)據(jù)存儲(chǔ)為字節(jié)數(shù)組byte array楷怒。ZooKeeper并不直接提供解析支持。我們可以使用Protocol buffers 瓦灶, Thrift鸠删、Avro或者M(jìn)essagePack等序列化(Serialization)包來(lái)方便的處理保存于znode節(jié)點(diǎn)的數(shù)據(jù)格式。不過(guò)有時(shí)候UTF-8和ASC2編碼的字符串就夠用了贼陶。

zookeeper的API暴露了以下的方法:

carete ?/path data

創(chuàng)建一個(gè)名為 /path 的node 節(jié)點(diǎn)刃泡,包含數(shù)據(jù)data巧娱。

delete /path

刪除名為 /path的znode

exists /path

檢查是否存在名為 /path的節(jié)點(diǎn)

setData /path data

設(shè)置名為/path 的znode的數(shù)據(jù)為data

getData /path

返回名為/path節(jié)點(diǎn)的數(shù)據(jù)信息

getChildren /path

返回所有 /path節(jié)點(diǎn)的所有子節(jié)點(diǎn)的列表。

zookeeper客戶(hù)端連接到zookeeper服務(wù)烘贴,通過(guò)API調(diào)用來(lái)建立會(huì)話(huà)session禁添。

2.1.2 znode的不同類(lèi)型

持久檢點(diǎn)和臨時(shí)節(jié)點(diǎn)

znode節(jié)點(diǎn)可以是持久(persistent)節(jié)點(diǎn),還可以是臨時(shí)(ephemeral)節(jié)點(diǎn)桨踪。持久的znode老翘,如/path,只能通過(guò)調(diào)用delete來(lái)進(jìn)行刪除馒闷。臨時(shí)的znode與之相反酪捡,當(dāng)穿件該節(jié)點(diǎn)的客戶(hù)端崩潰的時(shí)或者關(guān)閉與zookeeper的鏈接時(shí)叁征,這個(gè)節(jié)點(diǎn)就會(huì)被刪除纳账。

持久znode是一種非常有用的znode,可以通過(guò)持久類(lèi)型的znode為應(yīng)用保存一些數(shù)據(jù)捺疼。

臨時(shí)znode疏虫,在一下兩種情況下會(huì)被刪除;

1啤呼、當(dāng)創(chuàng)建該znode的客戶(hù)端的會(huì)話(huà)因超時(shí)或者注定關(guān)閉而終止

2卧秘、當(dāng)某個(gè)客戶(hù)端主動(dòng)刪除該節(jié)點(diǎn)時(shí)候。

版本機(jī)制





假設(shè)客戶(hù)端C1對(duì)znode /config寫(xiě)入一些配置信息官扣,如果另一個(gè)客戶(hù)端C2同時(shí)更新了這個(gè)znode翅敌,此時(shí)c1的版本號(hào)已經(jīng)過(guò)期,c1調(diào)用setData一定不會(huì)成功惕蹄。使用版本機(jī)制有效避免了以上情況蚯涮。在這個(gè)例子中,C1在寫(xiě)入數(shù)據(jù)使用的版本無(wú)法匹配卖陵,是的操作失敗遭顶。

2.2zookeeper架構(gòu)

zookeeper服務(wù)器端運(yùn)行于兩種模式下:獨(dú)立模式standalone,沖裁模式quorum泪蔫。

在仲裁模式下棒旗,具有一組zookeeper服務(wù),我們稱(chēng)之為zookeeper集合(zookeeper ensemble)撩荣,它們之前可以進(jìn)行狀態(tài)復(fù)制铣揉,并同時(shí)為服務(wù)于客戶(hù)端請(qǐng)求。






1餐曹、在仲裁模式下老速,利用公共管理領(lǐng)域最小有效投票數(shù),在zookeeper中凸主,則是指為了使得zookeeper工作必須有效的運(yùn)行的服務(wù)的最小數(shù)量橘券。這個(gè)數(shù)字也是服務(wù)器告知客戶(hù)端安全數(shù)據(jù)前,需要保存客戶(hù)端數(shù)據(jù)的最小數(shù)量。

2.2.2會(huì)話(huà)

旁舰,對(duì)zookeeper集合執(zhí)行任何請(qǐng)求前锋华,一個(gè)客戶(hù)端必先與服務(wù)建立會(huì)話(huà)。會(huì)話(huà)的概念非常重要箭窜,對(duì)ZooKeeper的運(yùn)行也非常關(guān)鍵毯焕。客戶(hù)端提交給zookeeper的所有操作均關(guān)聯(lián)在一個(gè)會(huì)話(huà)上磺樱。當(dāng)一個(gè)會(huì)話(huà)因某種原因而中止時(shí)纳猫,在這個(gè)會(huì)話(huà)期間創(chuàng)建的臨時(shí)節(jié)點(diǎn)會(huì)消失。

2.3.2 會(huì)話(huà)的狀態(tài)和聲明周期

會(huì)話(huà)的生命周期lifetime是指會(huì)話(huà)從創(chuàng)建到結(jié)束的時(shí)期竹捉,無(wú)論是會(huì)話(huà)的正常關(guān)閉還是因超時(shí)而導(dǎo)致過(guò)期芜辕。

狀態(tài):CONNECTING\CONNECTED\CLOSED\NOT_CONNECTED

開(kāi)始——>NOT_CONNECTED

———>CONNECTING

———>CONNECTED

當(dāng)發(fā)生斷開(kāi)或者無(wú)法收到服務(wù)器超時(shí)時(shí)

————>CONNECTING

當(dāng)服務(wù)器確認(rèn)會(huì)話(huà)有效后,狀態(tài)會(huì)轉(zhuǎn)回CONNECTED狀態(tài)块差。

否則聲明會(huì)話(huà)過(guò)期侵续,然后轉(zhuǎn)到CLOSED狀態(tài)。

———

創(chuàng)建一個(gè)會(huì)時(shí)憨闰,你需要設(shè)置會(huì)話(huà)超時(shí)這個(gè)重要的參數(shù)状蜗,這個(gè)參數(shù)設(shè)置了zookeeper服務(wù)允許會(huì)話(huà)

被聲明為超時(shí)之前存在的時(shí)間。如果經(jīng)過(guò)時(shí)間t之后鹉动,服務(wù)接受不到這個(gè)會(huì)話(huà)的任何消息轧坎,服務(wù)就會(huì)聲明會(huì)話(huà)過(guò)期。而在客戶(hù)端側(cè)泽示,如果經(jīng)過(guò)t/3的時(shí)間未收到任何消息缸血,客戶(hù)端將向服務(wù)器發(fā)送心跳消息。經(jīng)過(guò)2t/3的時(shí)間后边琉,zookeeper客戶(hù)端開(kāi)始尋找其他的服務(wù)器属百,而此時(shí)它還有t/3的時(shí)間去尋找。

尋找可用服務(wù)器列表是通過(guò)給服務(wù)器發(fā)送可用服務(wù)器地址列表的方式實(shí)現(xiàn)变姨。

2.3.3zookeeper與仲裁模式

配置:

tickTime=2000

initLimit=10

synclimit=5

dataDir=./data

clientPort=2181

server.1=127.0.0.1:2222:2223

server.2=127.0.0.1:3333:3334

server.3=127.0.0.1:4444:4445

每一個(gè)server.h項(xiàng)指定了編號(hào)為n的zookeeper服務(wù)器使用的地址和端口號(hào)族扰。每個(gè)server.h項(xiàng)通過(guò)冒號(hào)分隔為三部分,第一部分為服務(wù)器n的Ip地址或主機(jī)名稱(chēng)hostname定欧,第二部分和第三部分為T(mén)CP端口號(hào)渔呵,分別為仲裁通信和群首選舉。

穿件data目錄

mkdir z1

mkdir z1/data

mkdir z2

mkdir z2/data

mkdir z3

mkdir z3/data

當(dāng)啟動(dòng)一個(gè)服務(wù)時(shí)砍鸠,我們需要知道啟動(dòng)的是哪個(gè)服務(wù)器扩氢,一個(gè)服務(wù)器通過(guò)讀取data目錄下的名為myid的文件來(lái)獲得服務(wù)器ID信息,通過(guò)以下命令來(lái)創(chuàng)建這些文件

echo 1> z1/data/myid

echo 2> z2/data/myid

echo 3 > z3/data/myid

在同一臺(tái)機(jī)器上需要?jiǎng)?chuàng)建z1/z1.cfg ? z2/z2.cfg ?z3/z3.cfg

zkServer.sh ./z1.cfg

注意:簡(jiǎn)單的負(fù)載均衡

客戶(hù)端以隨機(jī)順序連接串中的服務(wù)器爷辱。這樣可以用zookeeper來(lái)實(shí)現(xiàn)一個(gè)簡(jiǎn)單的負(fù)載均衡录豺。不過(guò)客戶(hù)端無(wú)法指定優(yōu)先選擇的服務(wù)器來(lái)進(jìn)行連接朦肘。例如我們有5個(gè)zookeeper服務(wù)器的集合,

第二部分

使用zookeeper進(jìn)行開(kāi)發(fā)

例子代碼

https://github.com/fpj/zookeeper-book-example

zookeeper java api進(jìn)行開(kāi)發(fā):

順序和ConnectionLossException

zooKeeper會(huì)嚴(yán)格維護(hù)執(zhí)行順序双饥,并提供強(qiáng)有力的有序保障媒抠,然而,在多線程下還是需要小心面對(duì)順序問(wèn)題咏花。在多線程下趴生,當(dāng)回調(diào)函數(shù)中包括重試邏輯的代碼時(shí),一些常見(jiàn)的場(chǎng)景都可能導(dǎo)致錯(cuò)誤發(fā)生昏翰。當(dāng)遇到connectionLossExceptin異常補(bǔ)發(fā)一個(gè)請(qǐng)求時(shí)苍匆,新建立的請(qǐng)求可能排序在其他線程中的請(qǐng)求之后,而實(shí)際上其他線程中的請(qǐng)求應(yīng)該在原來(lái)請(qǐng)求之后棚菊。

3.5任務(wù)隊(duì)列化

第四章 ?處理狀態(tài)變化

4.1 ?單次觸發(fā)器

我們所說(shuō)的事件(event)表示一個(gè)znode節(jié)點(diǎn)執(zhí)行更新操作浸踩。而一個(gè)監(jiān)視點(diǎn)(watch)表示一個(gè)與之關(guān)聯(lián)的znode節(jié)點(diǎn)和時(shí)間類(lèi)型組成的單次觸發(fā)器(例如:znode節(jié)點(diǎn)的數(shù)據(jù)被賦值,或znode節(jié)點(diǎn)被刪除)窍株。當(dāng)一個(gè)監(jiān)視點(diǎn)被一個(gè)事件觸發(fā)時(shí)民轴,就會(huì)產(chǎn)生一個(gè)通知(notification)攻柠。通知是注冊(cè)了監(jiān)視點(diǎn)的應(yīng)用客戶(hù)端收到的事件報(bào)告的消息球订。

當(dāng)應(yīng)用程序注冊(cè)了一個(gè)監(jiān)視點(diǎn)來(lái)接收通知,匹配該監(jiān)視點(diǎn)條件的第一個(gè)事件會(huì)觸發(fā)監(jiān)視點(diǎn)的通知瑰钮。并且最多只觸發(fā)一次冒滩。當(dāng)znode節(jié)點(diǎn)/z被刪除,客戶(hù)端需要知道該變化(例如浪谴,表示備份主節(jié)點(diǎn))开睡,客戶(hù)端在/z節(jié)點(diǎn)執(zhí)行exists操作并設(shè)置監(jiān)視點(diǎn)標(biāo)志位,等待通知苟耻,客戶(hù)端會(huì)以回調(diào)函數(shù)的形式受到通知篇恒。

客戶(hù)端設(shè)置的每個(gè)監(jiān)視點(diǎn)與會(huì)話(huà)關(guān)聯(lián),如果會(huì)話(huà)過(guò)期凶杖,期待中的監(jiān)視點(diǎn)將會(huì)被刪除胁艰。不過(guò)監(jiān)視點(diǎn)可以擴(kuò)月不同的服務(wù)端連接而保持,例如智蝠,當(dāng)一個(gè)zookeeper客戶(hù)端與一個(gè)zookeeper服務(wù)端的連接斷開(kāi)后連接到集合中的另一個(gè)服務(wù)器腾么,客戶(hù)端會(huì)發(fā)送未觸發(fā)的監(jiān)視點(diǎn)列表,在注冊(cè)監(jiān)視點(diǎn)時(shí)杈湾,服務(wù)端將要檢查已監(jiān)視的znode節(jié)點(diǎn)在之前注冊(cè)監(jiān)視點(diǎn)之后是否已經(jīng)變化解虱,如果znode節(jié)點(diǎn)已經(jīng)發(fā)生變化,一個(gè)監(jiān)視點(diǎn)的事件就會(huì)被發(fā)送給客戶(hù)端漆撞,否則在新的服務(wù)端上注冊(cè)監(jiān)視點(diǎn)殴泰。

單次觸發(fā)是否會(huì)丟失事件

答案是肯定的于宙。一個(gè)應(yīng)用在接收到通知后,注冊(cè)另一個(gè)監(jiān)視點(diǎn)時(shí)悍汛,可能會(huì)丟失事件限煞,不過(guò),這個(gè)問(wèn)題需要再深入探討员凝,丟失事件通常并不是問(wèn)題署驻,因?yàn)槿魏卧诮邮芡ㄖc注冊(cè)新監(jiān)視點(diǎn)之間的變化情況,均可以通過(guò)讀取zookeeper的狀態(tài)信息來(lái)獲得健霹。

假設(shè)一個(gè)節(jié)點(diǎn)接收到一個(gè)新任務(wù)分配給它的通知旺上,為了接受新任務(wù),從節(jié)點(diǎn)讀取任務(wù)列表糖埋,如果在通知接收后宣吱,又給這個(gè)從節(jié)點(diǎn)分配了更多的任務(wù),通過(guò)getchildren調(diào)用任務(wù)獲取任務(wù)列表時(shí)會(huì)返回所有的任務(wù)瞳别。同時(shí)調(diào)用getchildren時(shí)也可以設(shè)置新的監(jiān)視點(diǎn)征候,從而保證從節(jié)點(diǎn)不會(huì)丟失任務(wù)。

實(shí)際上祟敛,將多個(gè)事件分?jǐn)偟揭粋€(gè)通知上是具有積極的作用疤坝,比如,應(yīng)用進(jìn)行高頻率的更新操作時(shí)馆铁,這種通知機(jī)制比每個(gè)時(shí)間都發(fā)送通知更加輕量化跑揉。舉例子,如果每個(gè)通知平均補(bǔ)貨兩個(gè)事件埠巨,我們?yōu)槊總€(gè)時(shí)間只產(chǎn)生0.5個(gè)通知历谍,而不是每個(gè)事件1個(gè)通知。

4.2如何設(shè)置監(jiān)視點(diǎn)

Zookeeper的API中的所有讀操作:getData辣垒,getChildren和exits望侈,均可以選擇在讀取的znode節(jié)點(diǎn)上設(shè)置監(jiān)視點(diǎn)。使用監(jiān)視點(diǎn)機(jī)制勋桶,我們需要實(shí)現(xiàn)watcher接口脱衙,實(shí)現(xiàn)其中的process方法:

public void process(WatchedEvent event);

zookeeper會(huì)話(huà)狀態(tài):keeperSate:Disconnected哥遮、SyncConnected岂丘、AuthFailed、ConnectedReadOnly眠饮、SasAuthenticated和Expired奥帘。

事件類(lèi)型(EventType):NodeCreated、NodeDeleted仪召、NodeDataChanged寨蹋、NodeChildrenChanged和None松蒜。

NodeCreated

通過(guò)exists調(diào)用設(shè)置一個(gè)監(jiān)視點(diǎn)。

NodeDeleted

通過(guò)exists或者getData調(diào)用設(shè)置監(jiān)視點(diǎn)已旧。

NodeDataChanged

通過(guò)exists或者getData調(diào)用設(shè)置監(jiān)視點(diǎn)

nodeChildrenChanged

通過(guò)getChildren調(diào)用設(shè)置監(jiān)視點(diǎn)秸苗。

4.3普遍模型

1、進(jìn)行調(diào)用異步

2运褪、實(shí)現(xiàn)回調(diào)對(duì)象惊楼,并傳入異步調(diào)用函數(shù)中

3、如果操作需要設(shè)置監(jiān)視點(diǎn)秸讹,實(shí)現(xiàn)一個(gè)watcher對(duì)象檀咙,并傳入異步調(diào)用函數(shù)中。

4.4主從模式的例子

現(xiàn)在璃诀,我們通過(guò)主從模式的例子來(lái)看看如何處理狀態(tài)的變化弧可。以下為一個(gè)任務(wù)列表,一個(gè)組件需要等待處理的變化情況:

1劣欢、管理權(quán)變化

2棕诵、主節(jié)點(diǎn)等待從節(jié)點(diǎn)列表的變化

3、主節(jié)點(diǎn)等待新任務(wù)進(jìn)行分配

4凿将、從節(jié)點(diǎn)等待分配新任務(wù)

5校套、客戶(hù)端等待任務(wù)的執(zhí)行結(jié)果

4.5另一種調(diào)用方式

我們希望大多數(shù)應(yīng)用采用我們之前所討論的模式,即使是該模式的各種變體也可以丸相。我們專(zhuān)注于異步API搔确,并且建議開(kāi)發(fā)者也使用異步的方式彼棍,異步API可以讓?xiě)?yīng)用程序變得更加有效使用zookeeper資源灭忠、同時(shí)獲得更高的性能。

8座硕、Curator ? ? Zookeeper API的高級(jí)封裝庫(kù)

Curator作為zookeeper的一個(gè)高層次封裝庫(kù)弛作,為開(kāi)發(fā)人員封裝了一組開(kāi)發(fā)庫(kù),Curator的核心目的是為你管理zookeeper的相關(guān)操作

CuratorFramework

8.2 ?劉暢式API

流暢式API可以讓我們編寫(xiě)鏈?zhǔn)秸{(diào)用的代碼华匾,而不用在進(jìn)行請(qǐng)求操作時(shí)采用嚴(yán)格的簽名方案映琳。

實(shí)現(xiàn)異步調(diào)用的回調(diào)處理。假設(shè)在之前的調(diào)用中蜘拉,回調(diào)方式將會(huì)通過(guò)create事件傳遞給注冊(cè)的監(jiān)聽(tīng)器萨西。inBackground調(diào)用可以傳入一個(gè)上下文對(duì)象,銅鼓該參數(shù)可以傳入一個(gè)具體的回調(diào)方法的實(shí)現(xiàn)旭旭。

第9章

ZooKeeper 內(nèi)部原理

服務(wù)器對(duì)客戶(hù)端發(fā)送的請(qǐng)求操作了哪些工作谎脯?

群首和追隨者組成了保障狀態(tài)變化有序的核心實(shí)體,同時(shí)還存在第三類(lèi)服務(wù)器持寄,稱(chēng)為觀察者(observer)源梭。

觀察者不會(huì)參與決策哪些請(qǐng)求可被接受的過(guò)程娱俺,只是觀察決策的結(jié)果,觀察者的設(shè)計(jì)師為了系統(tǒng)的可擴(kuò)展性废麻。

那些會(huì)改變Zookeeper狀態(tài)的客戶(hù)端請(qǐng)求create荠卷、delete和setData)將會(huì)被轉(zhuǎn)發(fā)給群首、群首執(zhí)行相應(yīng)的請(qǐng)求烛愧,并形成狀態(tài)的更新油宜,我們成為事務(wù)(transaction)

事務(wù)的冪等性:可以對(duì)同一個(gè)事務(wù)執(zhí)行多次,得到的結(jié)果都一樣怜姿,前提是我們確保多個(gè)事務(wù)的執(zhí)行順序每次都是一樣的验庙。事務(wù)的冪等性可以讓我們?cè)谶M(jìn)行恢復(fù)處理時(shí)更加簡(jiǎn)單。

當(dāng)群首產(chǎn)生了一個(gè)事務(wù)社牲,就會(huì)為該事務(wù)分配一個(gè)表示符粪薛,我們稱(chēng)之為zookeeper會(huì)話(huà)ID (zxid),通過(guò)zxid對(duì)事務(wù)進(jìn)行標(biāo)識(shí)搏恤,就可以按照群首所指定的順序在各個(gè)服務(wù)器中按序執(zhí)行违寿。

服務(wù)器之間在進(jìn)行新的群首選舉時(shí)也會(huì)交換zxid信息,這樣就可以知道哪個(gè)無(wú)故障服務(wù)器接受了更多的事務(wù)熟空,并可以同步他們之間的狀態(tài)信息藤巢。這樣就知道哪個(gè)無(wú)故障服務(wù)器接受了更多的事務(wù),并可以同步他們之間的狀態(tài)信息息罗。

zxid為一個(gè)long型64位整數(shù)掂咒,分為兩部分:時(shí)間戳(epoch)部分和計(jì)數(shù)器counter兩部分,每部分為32位迈喉,在我們討論zab協(xié)議時(shí)绍刮,我們就發(fā)現(xiàn)時(shí)間錯(cuò)epoch和計(jì)數(shù)器counter的具體作用,我們通過(guò)該協(xié)議來(lái)廣播各個(gè)服務(wù)器的狀態(tài)變更信息挨摸。

9.2群首選舉

設(shè)置群首的目的是為了對(duì)客戶(hù)端發(fā)起的zookeeper狀態(tài)變更請(qǐng)求進(jìn)行排序孩革,包括create、setData得运,delete操作膝蜈。群首將每一個(gè)請(qǐng)求轉(zhuǎn)化為一個(gè)事務(wù),將這些事務(wù)發(fā)送給追隨者熔掺,確保集群按照確定的順序接受并處理這些事務(wù)饱搏。

仲裁(quorum)

仲裁模式要求服務(wù)器之間兩兩相交。

每個(gè)服務(wù)器啟動(dòng)后進(jìn)入LOOKING狀態(tài)置逻,開(kāi)始選舉一個(gè)新的群首或查找已經(jīng)存在的群首推沸,如果群首已經(jīng)存在,其他服務(wù)器就會(huì)通知這個(gè)新啟動(dòng)的服務(wù)器诽偷,告知那個(gè)服務(wù)器是群首坤学,于此同時(shí)疯坤,新的服務(wù)器會(huì)與群首建立連接,以確保自己的狀態(tài)與群首一致深浮。

如果集群中所有的服務(wù)器均處于LOOKING狀態(tài)压怠,這些服務(wù)器之間就會(huì)進(jìn)行通信來(lái)選舉一個(gè)群首,通過(guò)信息交換對(duì)群首選舉達(dá)成共識(shí)的選擇飞苇,本次選舉過(guò)程中勝出的服務(wù)器將進(jìn)入LEADING狀態(tài)

對(duì)于群首選擇的消息菌瘫,我們稱(chēng)之為群首選舉通知消息(leader eletion notifications),或簡(jiǎn)單地稱(chēng)為通知(notifications)布卡。該協(xié)議非常簡(jiǎn)單雨让,當(dāng)一個(gè)服務(wù)器進(jìn)行LOOKING狀態(tài),就會(huì)向集群中每個(gè)服務(wù)器發(fā)送一個(gè)通知消息忿等,該消息中包括服務(wù)器的投標(biāo)vote信息栖忠,投票中包含服務(wù)器標(biāo)識(shí)符(sid)和最近執(zhí)行的事務(wù)的zxid信息。比如贸街,一個(gè)服務(wù)器所發(fā)送的投標(biāo)信息為(1庵寞,5),該服務(wù)器表示的sid為1薛匪,最近執(zhí)行的事務(wù)的zxid為5.

當(dāng)一個(gè)服務(wù)器收到一個(gè)投票信息捐川,該服務(wù)器將會(huì)根據(jù)以下規(guī)則修改自己的投票信息:

1、將收到的Voteid和votezxid作為標(biāo)識(shí)符逸尖,并獲取接收方當(dāng)前的投票中的zxid古沥,用myzxid和mysid表示接收方服務(wù)器自己的值

2、如果votezxid>myzxid或者votezxid = myzxid且 voteid>myid娇跟,保留當(dāng)前的投票信息岩齿。

3、否則逞频,修改自己的投票信息纯衍,將votezxid賦值給myzxid,將voteid賦值給mySid苗胀,簡(jiǎn)而言之,只有最新的服務(wù)器將贏得選舉瓦堵,因?yàn)槠鋼碛凶罱粋€(gè)的zxid基协,如果多個(gè)服務(wù)器擁有最新的zxid值,其中的sid值最大的將贏得選舉菇用。

查找群首

在Zookeeper中對(duì)應(yīng)實(shí)現(xiàn)選舉的java類(lèi)為QuorumPeer澜驮,其中的run方法實(shí)現(xiàn)了服務(wù)器的主要工作循環(huán)。當(dāng)進(jìn)入LOOKING狀態(tài)惋鸥,將會(huì)執(zhí)行l(wèi)ookForLeader方法來(lái)進(jìn)行群首的選舉杂穷,該方法主要執(zhí)行我們剛剛所討論為協(xié)議悍缠。在方法返回前,在該方法中會(huì)將服務(wù)器狀態(tài)設(shè)置為L(zhǎng)EADING或FOLLOWING狀態(tài)耐量,當(dāng)然還可能為OBSERVING狀態(tài)飞蚓,如果服務(wù)器稱(chēng)為群首,就會(huì)創(chuàng)建一個(gè)leader對(duì)象并運(yùn)行這個(gè)對(duì)象廊蜒。如果服務(wù)器為追隨者趴拧,就會(huì)創(chuàng)建一個(gè)Follower對(duì)象并進(jìn)行運(yùn)行。






并不是所有執(zhí)行過(guò)程山叮,服務(wù)器s2做出了錯(cuò)誤判斷著榴,選擇了另一個(gè)服務(wù)器s3不是服務(wù)器s1,雖然s1的zxid值更高屁倔,但在從服務(wù)器s1向服務(wù)器s2傳送消息時(shí)發(fā)生了網(wǎng)絡(luò)故障導(dǎo)致長(zhǎng)時(shí)間延遲脑又,與此同時(shí)腻要,服務(wù)器s2選擇服務(wù)器s3作為群首搬设,最終,服務(wù)器s1和服務(wù)器s3組成了仲裁數(shù)量quorum繁堡,并忽略服務(wù)器s2.





9.3 Zab:ZooKeeper原子廣播協(xié)議(ZooKeeper Atomic Broadcast protocol)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末瞎饲,一起剝皮案震驚了整個(gè)濱河市口叙,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌嗅战,老刑警劉巖妄田,帶你破解...
    沈念sama閱讀 206,126評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異驮捍,居然都是意外死亡疟呐,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,254評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門(mén)东且,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)启具,“玉大人,你說(shuō)我怎么就攤上這事珊泳÷撤耄” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 152,445評(píng)論 0 341
  • 文/不壞的土叔 我叫張陵色查,是天一觀的道長(zhǎng)薯演。 經(jīng)常有香客問(wèn)我,道長(zhǎng)秧了,這世上最難降的妖魔是什么跨扮? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,185評(píng)論 1 278
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上衡创,老公的妹妹穿的比我還像新娘帝嗡。我一直安慰自己,他們只是感情好璃氢,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,178評(píng)論 5 371
  • 文/花漫 我一把揭開(kāi)白布哟玷。 她就那樣靜靜地躺著,像睡著了一般拔莱。 火紅的嫁衣襯著肌膚如雪碗降。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 48,970評(píng)論 1 284
  • 那天塘秦,我揣著相機(jī)與錄音讼渊,去河邊找鬼。 笑死尊剔,一個(gè)胖子當(dāng)著我的面吹牛爪幻,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播须误,決...
    沈念sama閱讀 38,276評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼挨稿,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了京痢?” 一聲冷哼從身側(cè)響起奶甘,我...
    開(kāi)封第一講書(shū)人閱讀 36,927評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎祭椰,沒(méi)想到半個(gè)月后臭家,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,400評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡方淤,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,883評(píng)論 2 323
  • 正文 我和宋清朗相戀三年钉赁,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片携茂。...
    茶點(diǎn)故事閱讀 37,997評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡你踩,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出讳苦,到底是詐尸還是另有隱情带膜,我是刑警寧澤,帶...
    沈念sama閱讀 33,646評(píng)論 4 322
  • 正文 年R本政府宣布医吊,位于F島的核電站钱慢,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏卿堂。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,213評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望草描。 院中可真熱鬧览绿,春花似錦、人聲如沸穗慕。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,204評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)逛绵。三九已至怀各,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間术浪,已是汗流浹背瓢对。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,423評(píng)論 1 260
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留胰苏,地道東北人硕蛹。 一個(gè)月前我還...
    沈念sama閱讀 45,423評(píng)論 2 352
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像硕并,于是被迫代替她去往敵國(guó)和親法焰。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,722評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容

  • ZooKeeper 分布式過(guò)程協(xié)同技術(shù)詳解 簡(jiǎn)介 分布式系統(tǒng) 分布式系統(tǒng)是同時(shí)跨越多個(gè)物理主機(jī), 獨(dú)立運(yùn)行的多個(gè)軟...
    魯云飛_閱讀 2,630評(píng)論 0 1
  • 一倔毙、ZooKeeper的背景 1.1 認(rèn)識(shí)ZooKeeper ZooKeeper---譯名為“動(dòng)物園管理員”埃仪。動(dòng)物...
    algernoon閱讀 9,051評(píng)論 1 106
  • 本文將從系統(tǒng)模型卵蛉、序列化與協(xié)議、客戶(hù)端工作原理凯正、會(huì)話(huà)毙玻、服務(wù)端工作原理以及數(shù)據(jù)存儲(chǔ)等方面來(lái)揭示ZooKeeper的技...
    端木軒閱讀 3,783評(píng)論 0 42
  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)廊散,斷路器桑滩,智...
    卡卡羅2017閱讀 134,599評(píng)論 18 139
  • 一個(gè)真正的寫(xiě)數(shù)據(jù)流程是怎么樣的?一個(gè)真正的讀數(shù)據(jù)流程是怎么樣的允睹?一個(gè)真正的同步數(shù)據(jù)流程是怎么樣的运准?從哪里到哪里?什...
    時(shí)待吾閱讀 4,004評(píng)論 0 14