數(shù)據(jù)模型:
Zookeeper通過(guò)分層名稱空間來(lái)管理數(shù)據(jù)纫骑,和文件系統(tǒng)類(lèi)型送矩,唯一的不同點(diǎn)是每個(gè)znode既可以創(chuàng)建children赶撰,同時(shí)也可以存儲(chǔ)數(shù)據(jù)。每個(gè)znode的路徑是通過(guò)\分割的字符串糊啡,每個(gè)路徑都是唯一的拄查,不存在相對(duì)路徑。任意Unicode字符都可以用于構(gòu)建路徑棚蓄,除了一下幾個(gè)限制:
空字符串(\u0000)堕扶、\u0001 - \u001F和 \u007F、\u009F(不好展示)梭依、?\ud800 - uF8FF,稍算、\uFFF0 - uFFFF
.可以用于路徑里name的一部分,但是不能代表一個(gè)獨(dú)立的路徑役拴,因?yàn)閦node不存在相對(duì)路徑糊探,舉個(gè)例子:?"/a/b/./c"是不合法的,但是/a/b/c./c是合法的
數(shù)據(jù)節(jié)點(diǎn):ZNode
Zookeeper tree里每個(gè)數(shù)據(jù)節(jié)點(diǎn)都成為ZNode河闰。Znode里保存了數(shù)據(jù)狀態(tài)科平,包括版本號(hào)、acl訪問(wèn)權(quán)限姜性、時(shí)間戳等瞪慧。Zookeeper通過(guò)版本號(hào)和時(shí)間戳來(lái)驗(yàn)證緩存和協(xié)調(diào)更新。每次znode更新成功部念,他的版本號(hào)會(huì)遞增弃酌,無(wú)論什么時(shí)候客戶端檢索znode,他都會(huì)收到znode的版本號(hào)儡炼,當(dāng)客戶端更新或者刪除數(shù)據(jù)時(shí)妓湘,客戶端必須提供版本號(hào),如果znode當(dāng)前的版本號(hào)和客戶端提供的版本號(hào)不一致乌询,則操作會(huì)失敗多柑。
注意:znode、server楣责、quorum peers和ensemble的差別
In distributed application engineering, the word?node?can refer to a generic host machine, a server, a member of an ensemble, a client process, etc. In the ZooKeeper documentation,?znodes?refer to the data nodes.?Servers?refer to machines that make up the ZooKeeper service;?quorum peers?refer to the servers that make up an ensemble; client refers to any host or process which uses a ZooKeeper service.
監(jiān)聽(tīng)器:watcher
客戶端可以在znode上添加監(jiān)聽(tīng)器竣灌。當(dāng)znode發(fā)生變化的時(shí)候,添加在它上面的監(jiān)聽(tīng)器會(huì)被觸發(fā)秆麸,然后刪除初嘹。當(dāng)監(jiān)聽(tīng)器被觸發(fā)后,服務(wù)端會(huì)發(fā)送給客戶端一個(gè)通知沮趣。更多詳情請(qǐng)參考:http://zookeeper.apache.org/doc/current/zookeeperProgrammers.html#ch_zkWatches
數(shù)據(jù)訪問(wèn)權(quán)限:ACL
客戶端通過(guò)原子的方式讀寫(xiě)znode里存儲(chǔ)的數(shù)據(jù)屯烦,讀寫(xiě)操作都是對(duì)znode里所有數(shù)據(jù)生效,也就是說(shuō)房铭,無(wú)法對(duì)znode里數(shù)據(jù)的某個(gè)字段進(jìn)行讀寫(xiě)操作驻龟,每個(gè)znode都通過(guò)訪問(wèn)控制列表acl來(lái)進(jìn)行權(quán)限控制
Zookeeper的目標(biāo)不是為了提供傳統(tǒng)的數(shù)據(jù)庫(kù)服務(wù),也不擅長(zhǎng)存儲(chǔ)長(zhǎng)度太大的對(duì)象缸匪,它管理的是一些協(xié)調(diào)數(shù)據(jù)(分布式服務(wù)用于協(xié)調(diào)服務(wù)的數(shù)據(jù))翁狐,比如配置信息、集群狀態(tài)信息等凌蔬。這些數(shù)據(jù)通常來(lái)說(shuō)都比較小露懒,不超過(guò)kb級(jí)別。Zookeeper客戶端和服務(wù)端都會(huì)通過(guò)一定的校驗(yàn)來(lái)確保存儲(chǔ)在每個(gè)znode的數(shù)據(jù)大小不超過(guò)1Mb砂心。實(shí)際上懈词,平均數(shù)據(jù)大小應(yīng)該遠(yuǎn)比1Mb小。如果數(shù)據(jù)過(guò)大辩诞,Zookeeper需要花費(fèi)更多的時(shí)間來(lái)處理客戶端請(qǐng)求坎弯,并且數(shù)據(jù)的網(wǎng)絡(luò)傳輸時(shí)延和讀寫(xiě)存儲(chǔ)時(shí)延會(huì)增大,這在一定程度上會(huì)對(duì)某些操作產(chǎn)生影響译暂。如果碰到大數(shù)據(jù)存儲(chǔ)的場(chǎng)景抠忘,通常的做法是將數(shù)據(jù)存放到大數(shù)據(jù)存儲(chǔ)系統(tǒng)例如NFS或者HDFS,然后再Zookeeper里存放指向存儲(chǔ)地址的指針。
臨時(shí)節(jié)點(diǎn):
ZooKeeper還支持臨時(shí)節(jié)點(diǎn),當(dāng)session失效后遍搞,臨時(shí)節(jié)點(diǎn)會(huì)被刪除嘉汰,因此臨時(shí)節(jié)點(diǎn)不允許存在子節(jié)點(diǎn)。
有序節(jié)點(diǎn)-唯一命名空間:
當(dāng)創(chuàng)建znode的時(shí)候饺蚊,你可以通過(guò)Zookeeper在數(shù)據(jù)節(jié)點(diǎn)路徑的最后增加一個(gè)逐漸遞增的計(jì)數(shù)器,對(duì)于父節(jié)點(diǎn)來(lái)說(shuō),這個(gè)計(jì)數(shù)器是唯一的啦撮,格式為%010d(計(jì)數(shù)器以這種方式格式化以簡(jiǎn)化排序),比如說(shuō)?0000000001汪厨。計(jì)數(shù)器是一個(gè)帶符號(hào)整形赃春,由父節(jié)點(diǎn)維護(hù)。當(dāng)計(jì)數(shù)器大于2147483647時(shí)會(huì)造成溢出劫乱。
容器節(jié)點(diǎn)(Container Nodes):
Zookeeper3.5.3版本增加了容器節(jié)點(diǎn)织中,這種類(lèi)型的數(shù)據(jù)節(jié)點(diǎn)是為特定場(chǎng)景服務(wù)的锥涕,比如選主、鎖等狭吼。當(dāng)容器節(jié)點(diǎn)的最后一個(gè)子節(jié)點(diǎn)被刪除后层坠,服務(wù)端會(huì)隨后會(huì)在某個(gè)時(shí)間點(diǎn)將容器刪除。
限時(shí)節(jié)點(diǎn)(TTL Nodes):
Zookeeper3.5.3版本增加了限時(shí)節(jié)點(diǎn)刁笙,當(dāng)創(chuàng)建一個(gè)永久節(jié)點(diǎn)或者永久有序節(jié)點(diǎn)時(shí)破花,可以給這個(gè)節(jié)點(diǎn)增加一個(gè)時(shí)間屬性(毫秒為單位),當(dāng)指定時(shí)間內(nèi)節(jié)點(diǎn)沒(méi)有被修改疲吸,并且不存在子節(jié)點(diǎn)座每,那么服務(wù)端會(huì)在隨后的某個(gè)時(shí)間點(diǎn)將此節(jié)點(diǎn)刪除。注意:必須通過(guò)System屬性啟用TTL節(jié)點(diǎn)摘悴,因?yàn)槟J(rèn)情況下它們被禁用峭梳。如果你沒(méi)有在系統(tǒng)層面啟用TTL屬性,那么在添加的時(shí)候會(huì)拋出KeeperException.UnimplementedException異常
Zookeeper的時(shí)間機(jī)制:
Zookeeper通過(guò)多種機(jī)制來(lái)進(jìn)行時(shí)間回溯
ZXid:每次狀態(tài)變更的時(shí)候烦租,Zookeeper都會(huì)收到一個(gè)Zxid形式的時(shí)間戳(Zookeeper的事物id)延赌,這個(gè)id記錄了集群里所有的變更次數(shù),每次變更的時(shí)候叉橱,集群就會(huì)生成一個(gè)新的唯一zxid挫以。如果zxid1小于zxid2,就表示zxid1發(fā)生在zxid2之前窃祝。
版本號(hào):znode有三種類(lèi)型的版本號(hào)掐松,數(shù)據(jù)節(jié)點(diǎn)變更的次數(shù)、子節(jié)點(diǎn)的變更次數(shù)粪小、節(jié)點(diǎn)ACL配置的變更次數(shù)大磺,每次變化都會(huì)導(dǎo)致某個(gè)版本號(hào)遞增。
Ticks時(shí)鐘:集群通過(guò)時(shí)鐘來(lái)對(duì)多服務(wù)節(jié)點(diǎn)之間的比如session超時(shí)探膊、連接超時(shí)等進(jìn)行計(jì)時(shí)杠愧,最小會(huì)話超時(shí)時(shí)間是最小時(shí)鐘的2倍。如果客戶端設(shè)置的最小會(huì)話超時(shí)時(shí)間小于最小時(shí)鐘的兩倍逞壁,那么服務(wù)端會(huì)告知客戶端會(huì)話超時(shí)實(shí)際上是最小會(huì)話超時(shí)流济。
真實(shí)時(shí)間:
除了在znode創(chuàng)建和znode修改時(shí)將時(shí)間戳放入狀態(tài)數(shù)據(jù)之外,ZooKeeper根本不使用實(shí)時(shí)或時(shí)鐘時(shí)間腌闯。
Zookeeper的狀態(tài)數(shù)據(jù)結(jié)構(gòu):
數(shù)據(jù)節(jié)點(diǎn)的狀態(tài)結(jié)構(gòu)由一下字段構(gòu)成:
czxid?創(chuàng)建此znode的zxid
mzxid?最后一次更改此znode的zxid
pzxid?最后一次更改此節(jié)點(diǎn)子節(jié)點(diǎn)的zxid
ctime?從創(chuàng)建紀(jì)元開(kāi)始到創(chuàng)建此節(jié)點(diǎn)的毫秒數(shù)
mtime?從創(chuàng)建紀(jì)元開(kāi)始到最后一次更改節(jié)點(diǎn)的毫秒數(shù)
version?數(shù)據(jù)節(jié)點(diǎn)變更的次數(shù)
cversion?子節(jié)點(diǎn)的變更次數(shù)
aversion?節(jié)點(diǎn)ACL配置的變更次數(shù)
ephemeralOwner?此節(jié)點(diǎn)owner的會(huì)話id绳瘟,只對(duì)臨時(shí)節(jié)點(diǎn)有效
dataLength?節(jié)點(diǎn)數(shù)據(jù)大小
numChildren?子節(jié)點(diǎn)數(shù)量
Zookeeper Sessions
客戶端通過(guò)創(chuàng)建服務(wù)端句柄,并且綁定此句柄來(lái)建立會(huì)話連接姿骏。創(chuàng)建成功后服務(wù)端句柄進(jìn)入connecting狀態(tài)糖声,此時(shí)客戶端開(kāi)始嘗試和集群的某個(gè)server建立連接,一旦連接建立,服務(wù)端句柄進(jìn)入connected狀態(tài)蘸泻,在整個(gè)正常請(qǐng)求過(guò)程中琉苇,句柄會(huì)保持在connected狀態(tài)。但是當(dāng)發(fā)生不會(huì)回復(fù)的異常比如會(huì)話超時(shí)蟋恬、鑒權(quán)失敗等情況時(shí)翁潘,句柄會(huì)進(jìn)入closed狀態(tài)。如下圖所示
為了能夠和服務(wù)端建立會(huì)話連接歼争,客戶端必須提供host:port形式的服務(wù)端地址。比如?( "127.0.0.1:3000,127.0.0.1:3001")渗勘°迦蓿客戶端會(huì)隨機(jī)的選一個(gè)地址進(jìn)行連接。如果連接失敗旺坠,或者客戶端由于任何原因和服務(wù)端斷開(kāi)乔遮,客戶端會(huì)從地址列表里挑選另一個(gè)地址進(jìn)行連接,直到連接成功建立取刃。
Zookeeper3.2版本支持在服務(wù)端地址增加chroot蹋肮。比如當(dāng)你使用"127.0.0.1:3000,127.0.0.1:3001,127.0.0.1:3002/app/a"作為連接地址的時(shí)候,客戶端會(huì)進(jìn)入到此路徑璧疗,并且所有的操作都會(huì)基于此路徑之下坯辩。當(dāng)不同的服務(wù)需要使用不同的路徑時(shí),這個(gè)功能就顯得非常實(shí)用崩侠。
當(dāng)客戶端創(chuàng)建好句柄后漆魔,ZooKeeper會(huì)給客戶端創(chuàng)建一個(gè)64字節(jié)大小數(shù)字作為會(huì)話id。當(dāng)客戶端和不同的server節(jié)點(diǎn)通信的時(shí)候却音,它會(huì)將會(huì)話id寫(xiě)到握手信息里改抡。出于安全考慮,服務(wù)端給會(huì)話id創(chuàng)建了個(gè)只有集群機(jī)器能識(shí)別的密碼系瓢,在連接建立后阿纤,服務(wù)端會(huì)把這個(gè)密碼和會(huì)話id一起發(fā)送給客戶端。無(wú)論何時(shí)夷陋,客戶端在發(fā)送會(huì)話id的時(shí)候欠拾,都會(huì)帶著這個(gè)密碼。
客戶端通過(guò)方法調(diào)用創(chuàng)建session的時(shí)候肌稻,會(huì)傳入timeout參數(shù)清蚀,服務(wù)端收到請(qǐng)求后,會(huì)返回給客戶端可以接受的超時(shí)時(shí)間爹谭。目前服務(wù)端要求超時(shí)時(shí)間在2-20倍時(shí)鐘時(shí)間之中枷邪。
會(huì)話過(guò)去機(jī)制是在server端維護(hù)的,而不是客戶端,當(dāng)客戶端建立會(huì)話的時(shí)候东揣,它會(huì)傳入一個(gè)超時(shí)時(shí)間践惑,server端用這個(gè)值來(lái)判斷會(huì)話是否超時(shí)。如果服務(wù)端在超時(shí)時(shí)間內(nèi)沒(méi)有收到客戶端的心跳嘶卧,服務(wù)端就會(huì)判斷此會(huì)話已過(guò)期尔觉。此時(shí)集群會(huì)將這個(gè)會(huì)話周期內(nèi)創(chuàng)建的臨時(shí)節(jié)點(diǎn)全部刪除,并且觸發(fā)注冊(cè)在節(jié)點(diǎn)上的所有監(jiān)聽(tīng)器芥吟。除非重新建立tcp連接侦铜,否則客戶端會(huì)一直保持失聯(lián)狀態(tài)。重新建立連接后钟鸵,客戶端會(huì)收到回話超時(shí)提醒钉稍。
客戶端和服務(wù)端建立連接的時(shí)候,還會(huì)傳入一個(gè)默認(rèn)的監(jiān)聽(tīng)器棺耍。當(dāng)客戶端發(fā)送狀態(tài)變化的時(shí)候贡未,這個(gè)監(jiān)聽(tīng)器就會(huì)被觸發(fā)。比如當(dāng)客戶端和服務(wù)端斷連蒙袍、會(huì)話超時(shí)等俊卤,客戶端都能感知到。在建立新連接的時(shí)候害幅,監(jiān)聽(tīng)器收到的第一個(gè)事件是會(huì)話建立事件消恍,因此監(jiān)聽(tīng)器需要將初始狀態(tài)設(shè)置成disconnected。
客戶端通過(guò)發(fā)送請(qǐng)求來(lái)保持會(huì)話矫限,當(dāng)會(huì)話快超時(shí)但是沒(méi)有業(yè)務(wù)請(qǐng)求的話哺哼,客戶端會(huì)發(fā)送PING請(qǐng)求,通過(guò)這種方式既讓服務(wù)端知道客戶端依舊存活叼风,也讓服務(wù)端感知此會(huì)話依舊有效取董。PING的時(shí)間足夠保守,以確保有合理的時(shí)間來(lái)檢測(cè)死連接并重新連接到新服務(wù)器无宿。
連接建立以后茵汰,有兩種情況會(huì)導(dǎo)致API拋出connectionloss異常,1是當(dāng)會(huì)話失效后客戶端發(fā)起請(qǐng)求孽鸡,2是當(dāng)客戶端與server連接斷開(kāi)后的異步請(qǐng)求
Zookeeper3.2版本增加了SessionMovedException:當(dāng)一個(gè)服務(wù)端又收到了新會(huì)話id的請(qǐng)求時(shí)蹂午,原server端就會(huì)把老的會(huì)話id丟棄,此時(shí)就會(huì)拋出此異常彬碱。最常見(jiàn)的場(chǎng)景是客戶端像server1發(fā)送請(qǐng)求豆胸,由于網(wǎng)絡(luò)延時(shí)導(dǎo)致客戶端連接斷開(kāi),然后連到了新的server2巷疼,當(dāng)這個(gè)請(qǐng)求最終到達(dá)server1的時(shí)候晚胡,server1發(fā)現(xiàn)會(huì)話已經(jīng)過(guò)期,因此會(huì)移除此會(huì)話,關(guān)閉客戶端連接估盘。此時(shí)由于客戶端連接到了server2瓷患,因此它根本就不會(huì)感知到會(huì)話被移除。另一種情況是當(dāng)兩個(gè)客戶端用同一個(gè)會(huì)話id和密碼與服務(wù)端發(fā)起重連的時(shí)候遣妥,其中一個(gè)重連成功擅编,生成了新的會(huì)話id,第二個(gè)客戶端請(qǐng)求會(huì)被server端丟棄箫踩。這時(shí)候第二個(gè)客戶端就能夠捕獲到此異常了爱态。
服務(wù)端列表更新:
我們可以通過(guò)方法調(diào)用,用新的服務(wù)器列表來(lái)替換就的連接地址池班套。此方法可能會(huì)導(dǎo)致現(xiàn)有連接斷開(kāi)肢藐。這取決于重連算法。舉個(gè)例子:當(dāng)老的連接池有3個(gè)server吱韭,新的連接池在老的基礎(chǔ)上加了兩個(gè)server變成5個(gè),那么該算法將使客戶端以概率0.4丟棄與其連接的當(dāng)前主機(jī)的連接鱼的,并且導(dǎo)致客戶端隨機(jī)選擇一個(gè)新主機(jī)建立連接理盆。再舉一個(gè)例子,加上地址池里原有5臺(tái)server凑阶,我們把它去掉2臺(tái)猿规,連接到原3臺(tái)的客戶端會(huì)保持連接,連接到這兩臺(tái)的客戶端會(huì)斷開(kāi)連接宙橱,然后隨機(jī)從3臺(tái)中選一臺(tái)重新建立連接姨俩。
在第一個(gè)例子中,如果客戶端重連到所有新的server失敗师郑,那么它會(huì)繼續(xù)嘗試重連老的server环葵。接下來(lái)客戶端就進(jìn)入正常模式,下次重連的時(shí)候會(huì)從所有server中隨機(jī)選擇服務(wù)端進(jìn)行重連宝冕。
Zookeeper監(jiān)聽(tīng)器(Zookeeper Watcher):
用戶可以選擇給所有的讀請(qǐng)求添加監(jiān)聽(tīng)器张遭,我們來(lái)看下官方的定義:監(jiān)聽(tīng)事件是一次性觸發(fā)的,當(dāng)數(shù)據(jù)發(fā)送變化時(shí)地梨,監(jiān)聽(tīng)事件會(huì)被發(fā)送給設(shè)置了監(jiān)聽(tīng)器的客戶端菊卷,三個(gè)重點(diǎn):
1、觸發(fā)一次:當(dāng)一個(gè)客戶端發(fā)送了getData("/znode1", true)?請(qǐng)求宝剖,然后znode1數(shù)據(jù)發(fā)生了改變洁闰,此時(shí)在znode1上添加了讀事件的客戶端會(huì)收到一個(gè)讀事件,但是當(dāng)后面znode1再次發(fā)生變化后万细,客戶端不會(huì)再收到此事件了扑眉。
2、發(fā)送給客戶端:這意味著在事件到達(dá)客戶端時(shí),有可能實(shí)際的操作結(jié)果還沒(méi)有達(dá)到客戶端襟雷。事件是通過(guò)異步的方式發(fā)送給客戶端的刃滓,Zookeeper提供了一種機(jī)制保證順序性:在事件到達(dá)客戶端之前,客戶端不會(huì)看到數(shù)據(jù)的變化耸弄。由于網(wǎng)絡(luò)延時(shí)或者某些原因咧虎,Zookeeper無(wú)法保證不同的客戶端在同一時(shí)刻獲取到同一事件,但是它能保證事件變化和數(shù)據(jù)執(zhí)行結(jié)果達(dá)到的時(shí)序性计呈。
3砰诵、添加在數(shù)據(jù)上的監(jiān)聽(tīng)器:指的是數(shù)據(jù)改變的方式“葡裕可以理解Zookeeper有兩種類(lèi)型的監(jiān)聽(tīng)器茁彭,數(shù)據(jù)節(jié)點(diǎn)監(jiān)聽(tīng)器和子節(jié)點(diǎn)監(jiān)聽(tīng)器。getData() 和 exists() 用于設(shè)置數(shù)據(jù)監(jiān)聽(tīng)器扶歪。getChildren() 用于設(shè)置子節(jié)點(diǎn)監(jiān)聽(tīng)器理肺。因此setData()會(huì)觸發(fā)數(shù)據(jù)監(jiān)聽(tīng)器,create()會(huì)觸發(fā)數(shù)據(jù)節(jié)點(diǎn)監(jiān)聽(tīng)器和父節(jié)點(diǎn)的子節(jié)點(diǎn)監(jiān)聽(tīng)器善镰。delete()會(huì)觸發(fā)數(shù)據(jù)節(jié)點(diǎn)監(jiān)聽(tīng)器妹萨、本節(jié)點(diǎn)的子節(jié)點(diǎn)監(jiān)聽(tīng)器和父節(jié)點(diǎn)的子節(jié)點(diǎn)監(jiān)聽(tīng)器
客戶端在和某個(gè)server建立連接后,相關(guān)的znode監(jiān)聽(tīng)器設(shè)置會(huì)保存在此server端炫欺。當(dāng)客戶端連接到新服務(wù)器時(shí)乎完,將針對(duì)任何會(huì)話事件觸發(fā)監(jiān)聽(tīng)器。 從服務(wù)器斷開(kāi)連接時(shí)不會(huì)收到監(jiān)聽(tīng)事件品洛,所以當(dāng)和新server建立連接后树姨,如果有必要,需要將原來(lái)監(jiān)聽(tīng)器全部重新注冊(cè)一遍桥状。舉個(gè)事件丟失的例子:在斷連期間帽揪,如果一個(gè)znode被創(chuàng)建然后又被刪除了,那么這個(gè)客戶端在重連后岛宦,會(huì)收不到znode的existence事件台丛。
監(jiān)聽(tīng)器的語(yǔ)義(Semantics of Watches):
我們可以通過(guò)3個(gè)讀操作來(lái)添加監(jiān)聽(tīng)器:exists, getData, 和 getChildren。以下例子詳細(xì)的介紹了如何添加監(jiān)聽(tīng)器以及觸發(fā)監(jiān)聽(tīng)器的事件:
Created event:?通過(guò)調(diào)用exists來(lái)添加
Deleted event:?通過(guò)調(diào)用exists, getData, 和 getChildren來(lái)添加
Changed event:?通過(guò)調(diào)用exists 和 getData來(lái)添加
Child event:?通過(guò)調(diào)用getChildren來(lái)添加
刪除監(jiān)聽(tīng)器:
我們可以通過(guò)removeWatches來(lái)刪除監(jiān)聽(tīng)器砾肺。以下列出了當(dāng)監(jiān)聽(tīng)器被成功刪除后會(huì)觸發(fā)的事件:
Child Remove event:?通過(guò)調(diào)用getChildren添加的監(jiān)聽(tīng)器
Data Remove event:?通過(guò)電影exists 或者 getData添加的監(jiān)聽(tīng)器
Zookeeper訪問(wèn)權(quán)限控制:
Zookeeper的權(quán)限訪問(wèn)控制和Unix文件訪問(wèn)控制差不多挽霉,它使用權(quán)限位來(lái)允許/禁止針對(duì)節(jié)點(diǎn)的各種操作以及權(quán)限的范圍。不同的是他不是使用3位來(lái)控制權(quán)限变汪,在Zookeeper里侠坎,znode沒(méi)有owner的概念,ACL指定ID和這些ID對(duì)應(yīng)的權(quán)限集裙盾。
注意实胸,ACL權(quán)限通常情況下知識(shí)針對(duì)znode有效他嫡,而不是針對(duì)子節(jié)點(diǎn)。Ids通過(guò)scheme:expression來(lái)定義庐完。schema代表了認(rèn)證方式钢属,比如?ip:172.16.16.1? 代表使用ip為172.16.16.1的認(rèn)證方式,而digest:bob:password代表使用用戶名為bob和密碼認(rèn)證的方式门躯。當(dāng)客戶端連接到ZooKeeper并對(duì)其自身進(jìn)行身份驗(yàn)證時(shí)淆党,ZooKeeper會(huì)將與客戶端對(duì)應(yīng)的所有ID與客戶端連接相關(guān)聯(lián)。 當(dāng)客戶端嘗試訪問(wèn)節(jié)點(diǎn)時(shí)讶凉,將根據(jù)znode的ACL檢查這些ID染乌。ACLs由(scheme:expression, perms)構(gòu)成。舉個(gè)例子:?(ip:19.22.0.0/16, READ)?代表給ip段添加讀權(quán)限懂讯。
ACL權(quán)限:
Zookeeper支持以下幾種權(quán)限:
CREATE: you can create a child node
READ: you can get data from a node and list its children.
WRITE: you can set data for a node
DELETE: you can delete a child node
ADMIN: you can set permissions
CREATE和DELETE權(quán)限已從WRITE權(quán)限中刪除荷憋,以獲得更精細(xì)的訪問(wèn)控制。
CREATE?但是不?DELETE:客戶端通過(guò)在父目錄中創(chuàng)建ZooKeeper節(jié)點(diǎn)來(lái)創(chuàng)建請(qǐng)求褐望。 您希望所有客戶端都能夠添加勒庄,但只有請(qǐng)求處理器才能刪除
內(nèi)置ACL方案:
world?代表所有客戶端.
auth是一種特殊方案,它忽略任何提供的表達(dá)式瘫里,而是使用當(dāng)前用戶锅铅,憑據(jù)和方案。 在持久化ACL時(shí)减宣,ZooKeeper服務(wù)器會(huì)忽略所提供的任何表達(dá)式(無(wú)論是使用SASL身份驗(yàn)證還是用戶:密碼,如使用DIGEST身份驗(yàn)證)玩荠。 但是漆腌,仍必須在ACL中提供表達(dá)式,因?yàn)锳CL必須與表單scheme:expression:perms匹配阶冈。 提供此方案是為了方便闷尿,因?yàn)樗怯脩魟?chuàng)建znode然后將該znode的訪問(wèn)權(quán)限僅限于該用戶的常見(jiàn)用例。 如果沒(méi)有經(jīng)過(guò)身份驗(yàn)證的用戶女坑,則使用auth方案設(shè)置ACL將失敗填具。
digest?使用username:password字符串生成MD5哈希,然后將其用作ACL ID標(biāo)識(shí)匆骗。 通過(guò)以明文形式發(fā)送用戶名:密碼來(lái)完成身份驗(yàn)證劳景。 在ACL中使用時(shí),表達(dá)式將是用戶名:base64編碼的SHA1密碼摘要碉就。
ip?使用客戶端主機(jī)IP作為ACL ID標(biāo)識(shí)盟广。 ACL表達(dá)式的形式為addr / bits,其中addr的最高有效位與客戶端主機(jī)IP的最高有效位匹配
x509?還不是很了解
參考文章:http://zookeeper.apache.org/doc/current/zookeeperProgrammers.html