ZooKeeper是一個分布式的吵血,開放源碼的分布式應(yīng)用程序協(xié)調(diào)服務(wù),它包含一個簡單的原語集偷溺,分布式應(yīng)用程序可以基于它實現(xiàn)同步服務(wù)蹋辅,配置維護和命名服務(wù)等。Zookeeper是hadoop的一個子項目挫掏,其發(fā)展歷程無需贅述晕翠。在分布式應(yīng)用中,由于工程師不能很好地使用鎖機制砍濒,以及基于消息的協(xié)調(diào)機制不適合在某些應(yīng)用中使用淋肾,因此需要有一種可靠的、可擴展的爸邢、分布式的樊卓、可配置的協(xié)調(diào)機制來統(tǒng)一系統(tǒng)的狀態(tài)。Zookeeper的目的就在于此杠河。本文簡單分析zookeeper的工作原理碌尔,對于如何使用zookeeper不是本文討論的重點。
1 Zookeeper的基本概念
1.1 角色
Zookeeper中的角色主要有以下三類券敌,如下表所示:
系統(tǒng)模型如圖所示:
1.2 設(shè)計目的
1.最終一致性:client不論連接到哪個Server唾戚,展示給它都是同一個視圖,這是zookeeper最重要的性能待诅。
2 .可靠性:具有簡單叹坦、健壯、良好的性能卑雁,如果消息m被到一臺服務(wù)器接受募书,那么它將被所有的服務(wù)器接受。
3 .實時性:Zookeeper保證客戶端將在一個時間間隔范圍內(nèi)獲得服務(wù)器的更新信息测蹲,或者服務(wù)器失效的信息莹捡。但由于網(wǎng)絡(luò)延時等原因,Zookeeper不能保證兩個客戶端能同時得到剛更新的數(shù)據(jù)扣甲,如果需要最新數(shù)據(jù)篮赢,應(yīng)該在讀數(shù)據(jù)之前調(diào)用sync()接口。
4 .等待無關(guān)(wait-free):慢的或者失效的client不得干預(yù)快速的client的請求,使得每個client都能有效的等待启泣。
5.原子性:更新只能成功或者失敗媒咳,沒有中間狀態(tài)。
6 .順序性:包括全局有序和偏序兩種:全局有序是指如果在一臺服務(wù)器上消息a在消息b前發(fā)布种远,則在所有Server上消息a都將在消息b前被發(fā)布涩澡;偏序是指如果一個消息b在消息a后被同一個發(fā)送者發(fā)布,a必將排在b前面坠敷。
2 ZooKeeper的工作原理
Zookeeper的核心是原子廣播妙同,這個機制保證了各個Server之間的同步。實現(xiàn)這個機制的協(xié)議叫做Zab協(xié)議膝迎。Zab協(xié)議有兩種模式粥帚,它們分別是恢復(fù)模式(選主)和廣播模式(同步)。當(dāng)服務(wù)啟動或者在領(lǐng)導(dǎo)者崩潰后限次,Zab就進入了恢復(fù)模式芒涡,當(dāng)領(lǐng)導(dǎo)者被選舉出來,且大多數(shù)Server完成了和leader的狀態(tài)同步以后卖漫,恢復(fù)模式就結(jié)束了费尽。狀態(tài)同步保證了leader和Server具有相同的系統(tǒng)狀態(tài)。
為了保證事務(wù)的順序一致性羊始,zookeeper采用了遞增的事務(wù)id號(zxid)來標識事務(wù)旱幼。所有的提議(proposal)都在被提出的時候加上了zxid。實現(xiàn)中zxid是一個64位的數(shù)字突委,它高32位是epoch用來標識leader關(guān)系是否改變柏卤,每次一個leader被選出來,它都會有一個新的epoch匀油,標識當(dāng)前屬于那個leader的統(tǒng)治時期缘缚。低32位用于遞增計數(shù)。
每個Server在工作過程中有三種狀態(tài):
LOOKING:當(dāng)前Server不知道leader是誰敌蚜,正在搜尋
LEADING:當(dāng)前Server即為選舉出來的leader
FOLLOWING:leader已經(jīng)選舉出來桥滨,當(dāng)前Server與之同步
2.1 選主流程
當(dāng)leader崩潰或者leader失去大多數(shù)的follower,這時候zk進入恢復(fù)模式钝侠,恢復(fù)模式需要重新選舉出一個新的leader该园,讓所有的Server都恢復(fù)到一個正確的狀態(tài)酸舍。Zk的選舉算法有兩種:一種是基于basic paxos實現(xiàn)的帅韧,另外一種是基于fast paxos算法實現(xiàn)的。系統(tǒng)默認的選舉算法為fast paxos啃勉。先介紹basic paxos流程:
1 .選舉線程由當(dāng)前Server發(fā)起選舉的線程擔(dān)任忽舟,其主要功能是對投票結(jié)果進行統(tǒng)計,并選出推薦的Server;
2 .選舉線程首先向所有Server發(fā)起一次詢問(包括自己)叮阅;
3 .選舉線程收到回復(fù)后刁品,驗證是否是自己發(fā)起的詢問(驗證zxid是否一致),然后獲取對方的id(myid)浩姥,并存儲到當(dāng)前詢問對象列表中挑随,最后獲取對方提議的leader相關(guān)信息(id,zxid),并將這些信息存儲到當(dāng)次選舉的投票記錄表中勒叠;
4. ?收到所有Server回復(fù)以后兜挨,就計算出zxid最大的那個Server,并將這個Server相關(guān)信息設(shè)置成下一次要投票的Server眯分;
5. ?線程將當(dāng)前zxid最大的Server設(shè)置為當(dāng)前Server要推薦的Leader拌汇,如果此時獲勝的Server獲得n/2 + 1的Server票數(shù), 設(shè)置當(dāng)前推薦的leader為獲勝的Server弊决,將根據(jù)獲勝的Server相關(guān)信息設(shè)置自己的狀態(tài)噪舀,否則,繼續(xù)這個過程飘诗,直到leader被選舉出來与倡。
通過流程分析我們可以得出:要使Leader獲得多數(shù)Server的支持,則Server總數(shù)必須是奇數(shù)2n+1昆稿,且存活的Server的數(shù)目不得少于n+1.
每個Server啟動后都會重復(fù)以上流程蒸走。在恢復(fù)模式下,如果是剛從崩潰狀態(tài)恢復(fù)的或者剛啟動的server還會從磁盤快照中恢復(fù)數(shù)據(jù)和會話信息貌嫡,zk會記錄事務(wù)日志并定期進行快照比驻,方便在恢復(fù)時進行狀態(tài)恢復(fù)。選主的具體流程圖如下所示:
fast paxos流程是在選舉過程中岛抄,某Server首先向所有Server提議自己要成為leader别惦,當(dāng)其它Server收到提議以后,解決epoch和zxid的沖突夫椭,并接受對方的提議掸掸,然后向?qū)Ψ桨l(fā)送接受提議完成的消息,重復(fù)這個流程蹭秋,最后一定能選舉出Leader扰付。其流程圖如下所示:
2.2 同步流程
選完leader以后,zk就進入狀態(tài)同步過程仁讨。
1. leader等待server連接羽莺;
2 .Follower連接leader,將最大的zxid發(fā)送給leader洞豁;
3 .Leader根據(jù)follower的zxid確定同步點盐固;
4 .完成同步后通知follower 已經(jīng)成為uptodate狀態(tài)荒给;
5 .Follower收到uptodate消息后,又可以重新接受client的請求進行服務(wù)了刁卜。
流程圖如下所示:
2.3 工作流程
2.3.1 Leader工作流程
Leader主要有三個功能:
1 .恢復(fù)數(shù)據(jù)志电;
2 .維持與Learner的心跳,接收Learner請求并判斷Learner的請求消息類型蛔趴;
3 .Learner的消息類型主要有PING消息挑辆、REQUEST消息、ACK消息孝情、REVALIDATE消息之拨,根據(jù)不同的消息類型,進行不同的處理咧叭。
PING消息是指Learner的心跳信息蚀乔;REQUEST消息是Follower發(fā)送的提議信息,包括寫請求及同步請求菲茬;ACK消息是Follower的對提議的回復(fù)吉挣,超過半數(shù)的Follower通過,則commit該提議婉弹;REVALIDATE消息是用來延長SESSION有效時間睬魂。
Leader的工作流程簡圖如下所示,在實際實現(xiàn)中镀赌,流程要比下圖復(fù)雜得多氯哮,啟動了三個線程來實現(xiàn)功能。
2.3.2 Follower工作流程
Follower主要有四個功能:
1. 向Leader發(fā)送請求(PING消息商佛、REQUEST消息喉钢、ACK消息、REVALIDATE消息)良姆;
2 .接收Leader消息并進行處理肠虽;
3 .接收Client的請求,如果為寫請求玛追,發(fā)送給Leader進行投票税课;
4 .返回Client結(jié)果。
Follower的消息循環(huán)處理如下幾種來自Leader的消息:
1 .PING消息: 心跳消息痊剖;
2 .PROPOSAL消息:Leader發(fā)起的提案韩玩,要求Follower投票;
3 .COMMIT消息:服務(wù)器端最新一次提案的信息陆馁;
4 .UPTODATE消息:表明同步完成找颓;
5 .REVALIDATE消息:根據(jù)Leader的REVALIDATE結(jié)果,關(guān)閉待revalidate的session還是允許其接受消息氮惯;
6 .SYNC消息:返回SYNC結(jié)果到客戶端叮雳,這個消息最初由客戶端發(fā)起想暗,用來強制得到最新的更新妇汗。
Follower的工作流程簡圖如下所示帘不,在實際實現(xiàn)中,F(xiàn)ollower是通過5個線程來實現(xiàn)功能的杨箭。
對于observer的流程不再敘述寞焙,observer流程和Follower的唯一不同的地方就是observer不會參加leader發(fā)起的投票。
主流應(yīng)用場景:
Zookeeper的主流應(yīng)用場景實現(xiàn)思路(除去官方示例)
(1)配置管理集中式的配置管理在應(yīng)用集群中是非常常見的互婿,一般商業(yè)公司內(nèi)部都會實現(xiàn)一套集中的配置管理中心捣郊,應(yīng)對不同的應(yīng)用集群對于共享各自配置的需求,并且在配置變更時能夠通知到集群中的每一個機器慈参。
Zookeeper很容易實現(xiàn)這種集中式的配置管理呛牲,比如將APP1的所有配置配置到/APP1 znode下,APP1所有機器一啟動就對/APP1這個節(jié)點進行監(jiān)控(zk.exist("/APP1",true)),并且實現(xiàn)回調(diào)方法Watcher驮配,那么在zookeeper上/APP1 znode節(jié)點下數(shù)據(jù)發(fā)生變化的時候娘扩,每個機器都會收到通知,Watcher方法將會被執(zhí)行壮锻,那么應(yīng)用再取下數(shù)據(jù)即可(zk.getData("/APP1",false,null));
以上這個例子只是簡單的粗顆粒度配置監(jiān)控琐旁,細顆粒度的數(shù)據(jù)可以進行分層級監(jiān)控,這一切都是可以設(shè)計和控制的猜绣。
(2)集群管理
應(yīng)用集群中灰殴,我們常常需要讓每一個機器知道集群中(或依賴的其他某一個集群)哪些機器是活著的,并且在集群機器因為宕機掰邢,網(wǎng)絡(luò)斷鏈等原因能夠不在人工介入的情況下迅速通知到每一個機器牺陶。
Zookeeper同樣很容易實現(xiàn)這個功能,比如我在zookeeper服務(wù)器端有一個znode叫/APP1SERVERS,那么集群中每一個機器啟動的時候都去這個節(jié)點下創(chuàng)建一個EPHEMERAL類型的節(jié)點辣之,比如server1創(chuàng)建/APP1SERVERS/SERVER1(可以使用ip,保證不重復(fù))义图,server2創(chuàng)建/APP1SERVERS/SERVER2,然后SERVER1和SERVER2都watch /APP1SERVERS這個父節(jié)點召烂,那么也就是這個父節(jié)點下數(shù)據(jù)或者子節(jié)點變化都會通知對該節(jié)點進行watch的客戶端碱工。因為EPHEMERAL類型節(jié)點有一個很重要的特性,就是客戶端和服務(wù)器端連接斷掉或者session過期就會使節(jié)點消失奏夫,那么在某一個機器掛掉或者斷鏈的時候怕篷,其對應(yīng)的節(jié)點就會消失,然后集群中所有對/APP1SERVERS進行watch的客戶端都會收到通知酗昼,然后取得最新列表即可廊谓。
另外有一個應(yīng)用場景就是集群選master,一旦master掛掉能夠馬上能從slave中選出一個master,實現(xiàn)步驟和前者一樣,只是機器在啟動的時候在APP1SERVERS創(chuàng)建的節(jié)點類型變?yōu)镋PHEMERAL_SEQUENTIAL類型麻削,這樣每個節(jié)點會自動被編號
我們默認規(guī)定編號最小的為master,所以當(dāng)我們對/APP1SERVERS節(jié)點做監(jiān)控的時候蒸痹,得到服務(wù)器列表春弥,只要所有集群機器邏輯認為最小編號節(jié)點為master,那么master就被選出叠荠,而這個master宕機的時候匿沛,相應(yīng)的znode會消失,然后新的服務(wù)器列表就被推送到客戶端榛鼎,然后每個節(jié)點邏輯認為最小編號節(jié)點為master逃呼,這樣就做到動態(tài)master選舉。
Zookeeper 監(jiān)視(Watches) 簡介
Zookeeper C API 的聲明和描述在 include/zookeeper.h 中可以找到者娱,另外大部分的 Zookeeper C API 常量抡笼、結(jié)構(gòu)體聲明也在 zookeeper.h 中,如果如果你在使用 C API 是遇到不明白的地方黄鳍,最好看看 zookeeper.h推姻,或者自己使用 doxygen 生成 Zookeeper C API 的幫助文檔。
Zookeeper 中最有特色且最不容易理解的是監(jiān)視(Watches)框沟。Zookeeper 所有的讀操作——getData(),getChildren(), 和exists()都 可以設(shè)置監(jiān)視(watch)藏古,監(jiān)視事件可以理解為一次性的觸發(fā)器, 官方定義如下: a watch event is one-time trigger, sent to the client that set the watch, which occurs when the data for which the watch was set changes街望。對此需要作出如下理解:
(一次性觸發(fā))One-time trigger
當(dāng)設(shè)置監(jiān)視的數(shù)據(jù)發(fā)生改變時校翔,該監(jiān)視事件會被發(fā)送到客戶端,例如灾前,如果客戶端調(diào)用了 getData("/znode1", true) 并且稍后 /znode1 節(jié)點上的數(shù)據(jù)發(fā)生了改變或者被刪除了防症,客戶端將會獲取到 /znode1 發(fā)生變化的監(jiān)視事件,而如果 /znode1 再一次發(fā)生了變化哎甲,除非客戶端再次對 /znode1 設(shè)置監(jiān)視蔫敲,否則客戶端不會收到事件通知。
(發(fā)送至客戶端)Sent to the client
Zookeeper 客戶端和服務(wù)端是通過 socket 進行通信的炭玫,由于網(wǎng)絡(luò)存在故障奈嘿,所以監(jiān)視事件很有可能不會成功地到達客戶端,監(jiān)視事件是異步發(fā)送至監(jiān)視者的吞加,Zookeeper 本身提供了保序性(ordering guarantee):即客戶端只有首先看到了監(jiān)視事件后裙犹,才會感知到它所設(shè)置監(jiān)視的 znode 發(fā)生了變化(a client will never see a change for which it has set a watch until it first sees the watch event). 網(wǎng)絡(luò)延遲或者其他因素可能導(dǎo)致不同的客戶端在不同的時刻感知某一監(jiān)視事件,但是不同的客戶端所看到的一切具有一致的順序衔憨。
(被設(shè)置 watch 的數(shù)據(jù))The data for which the watch was set
這意味著 znode 節(jié)點本身具有不同的改變方式叶圃。你也可以想象 Zookeeper 維護了兩條監(jiān)視鏈表:數(shù)據(jù)監(jiān)視和子節(jié)點監(jiān)視(data watches and child watches) getData() and exists() 設(shè)置數(shù)據(jù)監(jiān)視,getChildren() 設(shè)置子節(jié)點監(jiān)視践图。 或者掺冠,你也可以想象 Zookeeper 設(shè)置的不同監(jiān)視返回不同的數(shù)據(jù),getData() 和 exists() 返回 znode 節(jié)點的相關(guān)信息码党,而 getChildren() 返回子節(jié)點列表德崭。因此斥黑, setData() 會觸發(fā)設(shè)置在某一節(jié)點上所設(shè)置的數(shù)據(jù)監(jiān)視(假定數(shù)據(jù)設(shè)置成功),而一次成功的 create() 操作則會出發(fā)當(dāng)前節(jié)點上所設(shè)置的數(shù)據(jù)監(jiān)視以及父節(jié)點的子節(jié)點監(jiān)視眉厨。一次成功的 delete() 操作將會觸發(fā)當(dāng)前節(jié)點的數(shù)據(jù)監(jiān)視和子節(jié)點監(jiān)視事件锌奴,同時也會觸發(fā)該節(jié)點父節(jié)點的child watch。
Zookeeper 中的監(jiān)視是輕量級的缺猛,因此容易設(shè)置缨叫、維護和分發(fā)椭符。當(dāng)客戶端與 Zookeeper 服務(wù)器端失去聯(lián)系時荔燎,客戶端并不會收到監(jiān)視事件的通知,只有當(dāng)客戶端重新連接后销钝,若在必要的情況下有咨,以前注冊的監(jiān)視會重新被注冊并觸發(fā),對于開發(fā)人員來說 這通常是透明的蒸健。只有一種情況會導(dǎo)致監(jiān)視事件的丟失座享,即:通過 exists() 設(shè)置了某個 znode 節(jié)點的監(jiān)視,但是如果某個客戶端在此 znode 節(jié)點被創(chuàng)建和刪除的時間間隔內(nèi)與 zookeeper 服務(wù)器失去了聯(lián)系似忧,該客戶端即使稍后重新連接 zookeeper服務(wù)器后也得不到事件通知渣叛。
Zookeeper C API 常量與部分結(jié)構(gòu)(struct)介紹
與 ACL 相關(guān)的結(jié)構(gòu)與常量:
struct Id 結(jié)構(gòu)為:
struct Id { ? ? char * scheme; ? ? char * id; };
struct ACL 結(jié)構(gòu)為:
struct ACL { ? ? int32_t perms; ? ? struct Id id; };
struct ACL_vector 結(jié)構(gòu)為:
struct ACL_vector { ? ? int32_t count; ? ? struct ACL *data; };
與 znode 訪問權(quán)限有關(guān)的常量
constintZOO_PERM_READ; //允許客戶端讀取 znode 節(jié)點的值以及子節(jié)點列表。
constintZOO_PERM_WRITE;// 允許客戶端設(shè)置 znode 節(jié)點的值盯捌。
constintZOO_PERM_CREATE; //允許客戶端在該 znode 節(jié)點下創(chuàng)建子節(jié)點淳衙。
constintZOO_PERM_DELETE;//允許客戶端刪除子節(jié)點。
constintZOO_PERM_ADMIN; //允許客戶端執(zhí)行 set_acl()饺著。
constintZOO_PERM_ALL;//允許客戶端執(zhí)行所有操作箫攀,等價與上述所有標志的或(OR) 。
與 ACL IDs 相關(guān)的常量
structId ZOO_ANYONE_ID_UNSAFE; //(‘world’,’anyone’)
structId ZOO_AUTH_IDS;// (‘a(chǎn)uth’,’’)
三種標準的 ACL
structACL_vector ZOO_OPEN_ACL_UNSAFE; //(ZOO_PERM_ALL,ZOO_ANYONE_ID_UNSAFE)
structACL_vector ZOO_READ_ACL_UNSAFE;// (ZOO_PERM_READ, ZOO_ANYONE_ID_UNSAFE)
structACL_vector ZOO_CREATOR_ALL_ACL; //(ZOO_PERM_ALL,ZOO_AUTH_IDS)
與 Interest 相關(guān)的常量:ZOOKEEPER_WRITE,ZOOKEEPER_READ
這 兩個常量用于標識感興趣的事件并通知 zookeeper 發(fā)生了哪些事件幼衰。Interest 常量可以進行組合或(OR)來標識多種興趣(multiple interests: write, read)靴跛,這兩個常量一般用于 zookeeper_interest() 和 zookeeper_process()兩個函數(shù)中。
與節(jié)點創(chuàng)建相關(guān)的常量:ZOO_EPHEMERAL,ZOO_SEQUENCE
zoo_create 函數(shù)標志渡嚣,ZOO_EPHEMERAL用來標識創(chuàng)建臨時節(jié)點梢睛,ZOO_SEQUENCE用來標識節(jié)點命名具有遞增的后綴序號(一般是節(jié)點名稱后填充 10 位字符的序號,如 /xyz0000000000, /xyz0000000001, /xyz0000000002, ...)识椰,同樣地绝葡,ZOO_EPHEMERAL,ZOO_SEQUENCE可以組合。
與連接狀態(tài) Stat 相關(guān)的常量
以下常量均與 Zookeeper 連接狀態(tài)有關(guān)裤唠,他們通常用作監(jiān)視器回調(diào)函數(shù)的參數(shù)挤牛。
ZOOAPI const intZOO_EXPIRED_SESSION_STATE
ZOOAPI const intZOO_AUTH_FAILED_STATE
ZOOAPI const intZOO_CONNECTING_STATE
ZOOAPI const intZOO_ASSOCIATING_STATE
ZOOAPI const intZOO_CONNECTED_STATE
與監(jiān)視類型(Watch Types)相關(guān)的常量
以下常量標識監(jiān)視事件的類型,他們通常用作監(jiān)視器回調(diào)函數(shù)的第一個參數(shù)种蘸。
ZOO_CREATED_EVENT; // 節(jié)點被創(chuàng)建(此前該節(jié)點不存在)墓赴,通過 zoo_exists() 設(shè)置監(jiān)視竞膳。
ZOO_DELETED_EVENT; // 節(jié)點被刪除,通過 zoo_exists() 和 zoo_get() 設(shè)置監(jiān)視诫硕。
ZOO_CHANGED_EVENT; // 節(jié)點發(fā)生變化坦辟,通過 zoo_exists() 和 zoo_get() 設(shè)置監(jiān)視。
ZOO_CHILD_EVENT; // 子節(jié)點事件章办,通過zoo_get_children() 和 zoo_get_children2()設(shè)置監(jiān)視锉走。
ZOO_NOTWATCHING_EVENT; // 監(jiān)視被移除。
Zookeeper C API 錯誤碼介紹ZOO_ERRORS
ZOK正常返回
ZSYSTEMERROR系統(tǒng)或服務(wù)器端錯誤(System and server-side errors)藕届,服務(wù)器不會拋出該錯誤挪蹭,該錯誤也只是用來標識錯誤范圍的,即大于該錯誤值休偶,且小于 ZAPIERROR 都是系統(tǒng)錯誤梁厉。
ZRUNTIMEINCONSISTENCY運行時非一致性錯誤。
ZDATAINCONSISTENCY數(shù)據(jù)非一致性錯誤踏兜。
ZCONNECTIONLOSSZookeeper 客戶端與服務(wù)器端失去連接
ZMARSHALLINGERROR在marshalling和unmarshalling數(shù)據(jù)時出現(xiàn)錯誤(Error while marshalling or unmarshalling data)
ZUNIMPLEMENTED該操作未實現(xiàn)(Operation is unimplemented)
ZOPERATIONTIMEOUT該操作超時(Operation timeout)
ZBADARGUMENTS非法參數(shù)錯誤(Invalid arguments)
ZINVALIDSTATE非法句柄狀態(tài)(Invliad zhandle state)
ZAPIERRORAPI 錯誤(API errors)词顾,服務(wù)器不會拋出該錯誤,該錯誤也只是用來標識錯誤范圍的碱妆,錯誤值大于該值的標識 API 錯誤肉盹,而小于該值的標識 ZSYSTEMERROR。
ZNONODE節(jié)點不存在(Node does not exist)
ZNOAUTH沒有經(jīng)過授權(quán)(Not authenticated)
ZBADVERSION版本沖突(Version conflict)
ZNOCHILDRENFOREPHEMERALS臨時節(jié)點不能擁有子節(jié)點(Ephemeral nodes may not have children)
ZNODEEXISTS節(jié)點已經(jīng)存在(The node already exists)
ZNOTEMPTY該節(jié)點具有自身的子節(jié)點(The node has children)
ZSESSIONEXPIRED會話過期(The session has been expired by the server)
ZINVALIDCALLBACK非法的回調(diào)函數(shù)(Invalid callback specified)
ZINVALIDACL非法的ACL(Invalid ACL specified)
ZAUTHFAILED客戶端授權(quán)失敗(Client authentication failed)
ZCLOSINGZookeeper 連接關(guān)閉(ZooKeeper is closing)
ZNOTHING并非錯誤疹尾,客戶端不需要處理服務(wù)器的響應(yīng)(not error, no server responses to process)
ZSESSIONMOVED會話轉(zhuǎn)移至其他服務(wù)器上忍,所以操作被忽略(session moved to another server, so operation is ignored)
Watch事件類型:
ZOO_CREATED_EVENT:節(jié)點創(chuàng)建事件,需要watch一個不存在的節(jié)點航棱,當(dāng)節(jié)點被創(chuàng)建時觸發(fā)睡雇,此watch通過zoo_exists()設(shè)置
ZOO_DELETED_EVENT:節(jié)點刪除事件,此watch通過zoo_exists()或zoo_get()設(shè)置
ZOO_CHANGED_EVENT:節(jié)點數(shù)據(jù)改變事件饮醇,此watch通過zoo_exists()或zoo_get()設(shè)置
ZOO_CHILD_EVENT:子節(jié)點列表改變事件它抱,此watch通過zoo_get_children()或zoo_get_children2()設(shè)置
ZOO_SESSION_EVENT:會話失效事件,客戶端與服務(wù)端斷開或重連時觸發(fā)
ZOO_NOTWATCHING_EVENT:watch移除事件朴艰,服務(wù)端出于某些原因不再為客戶端watch節(jié)點時觸發(fā)