摘要:可靠性一旦數(shù)據(jù)更新成功,將一直保持,直到新的更新。這是一種主動的分布式數(shù)據(jù)結(jié)構(gòu),能夠在外部情況發(fā)生變化時候主動修改數(shù)據(jù)項狀態(tài)的數(shù)據(jù)機構(gòu)。如果監(jiān)視節(jié)點狀態(tài)發(fā)生變化,則跳轉(zhuǎn)到第步,繼續(xù)進行后續(xù)的操作,直到退出鎖競爭。
題外話:從字面上來看,ZooKeeper表示動物園管理員,而Hadoop生態(tài)系統(tǒng)中,許多項目的Logo都采用了動物,比如Hadoop采用了大象的形象,所以可以ZooKeeper就是對這些動物進行一些管理工作的。
對于單機環(huán)境進程內(nèi)的協(xié)調(diào)方法,我們一般通過線程鎖來協(xié)調(diào)對共享數(shù)據(jù)的訪問以保證狀態(tài)的一致性。 但是分布式環(huán)境如何進行協(xié)調(diào)呢?于是,Google創(chuàng)造了Chubby,而ZooKeeper則是對于Chubby的一個開源實現(xiàn)。
ZooKeeper是一種為分布式應用所設(shè)計的高可用、高性能且一致的開源協(xié)調(diào)服務(wù),它提供了一項基本服務(wù):分布式鎖服務(wù)。由于ZooKeeper的開源特性,后來我們的開發(fā)者在分布式鎖的基礎(chǔ)上,摸索了出了其他的使用方法:配置維護、組服務(wù)、分布式消息隊列、分布式通知/協(xié)調(diào)等。它被設(shè)計為易于編程,使用文件系統(tǒng)目錄樹作為數(shù)據(jù)模型。
Zookeeper服務(wù)自身組成一個集群(2n+1個服務(wù)允許n個失效)。Zookeeper服務(wù)有兩個角色,一個是leader,負責寫服務(wù)和數(shù)據(jù)同步,剩下的是follower,提供讀服務(wù),leader失效后會在follower中重新選舉新的leader。
保證
順序一致性:按照客戶端發(fā)送請求的順序更新數(shù)據(jù)。
原子性:更新要么成功,要么失敗,不會出現(xiàn)部分更新。
單一性 :無論客戶端連接哪個server,都會看到同一個視圖。
可靠性:一旦數(shù)據(jù)更新成功,將一直保持,直到新的更新。
及時性:客戶端會在一個確定的時間內(nèi)得到最新的數(shù)據(jù)。
1、Zookeeper數(shù)據(jù)模型Znode
Zookeeper表現(xiàn)為一個分層的文件系統(tǒng)目錄樹結(jié)構(gòu)(不同于文件系統(tǒng)的是,節(jié)點可以有自己的數(shù)據(jù),而文件系統(tǒng)中的目錄節(jié)點只有子節(jié)點)。
Zookeeper Stat 結(jié)構(gòu) —— Zookeeper中的每個znode的stat都由下面的字段組成:
czxid - 引起這個znode創(chuàng)建的zxid
mzxid - znode最后更新的zxid
ctime - znode被創(chuàng)建的毫秒數(shù)(從1970年開始)
mtime - znode最后修改的毫秒數(shù)(從1970年開始)
version - znode數(shù)據(jù)變化號
cversion - znode子節(jié)點變化號
aversion - znode訪問控制列表的變化號
ephemeralOwner - 如果是臨時節(jié)點這個是znode擁有者的session id。如果不是臨時節(jié)點則是0。
dataLength - znode的數(shù)據(jù)長度
numChildren - znode子節(jié)點數(shù)量
關(guān)于數(shù)據(jù)模型的理解,建議參考:http://www.cnblogs.com/wuxl36...
簡單API——Zookeeper的設(shè)計目標的其中之一就是提供一個簡單的程序接口。因此,它只支持這些操作:
create - 在樹形結(jié)構(gòu)的位置中創(chuàng)建節(jié)點
delete - 刪除一個節(jié)點
exists - 測試節(jié)點在指定位置上是否存在
get data - 從節(jié)點上讀取數(shù)據(jù)
set data - 往節(jié)點寫入數(shù)據(jù)
get chilren - 檢索節(jié)點的子節(jié)點列表
sync - 等待傳輸數(shù)據(jù)
ZooKeeper的應用場景(1)統(tǒng)一命名服務(wù)
分布式應用中,通常需要有一套完整的命名規(guī)則,既能夠產(chǎn)生唯一的名稱又便于人識別和記住,通常情況下用樹形的名稱結(jié)構(gòu)是一個理想的選擇,樹形的名稱結(jié)構(gòu)是一個有層次的目錄結(jié)構(gòu),既對人友好又不會重復。說到這里你可能想到了 JNDI,沒錯 Zookeeper 的 Name Service 與 JNDI 能夠完成的功能是差不多的,它們都是將有層次的目錄結(jié)構(gòu)關(guān)聯(lián)到一定資源上,但是 Zookeeper 的 Name Service 更加是廣泛意義上的關(guān)聯(lián),也許你并不需要將名稱關(guān)聯(lián)到特定資源上,你可能只需要一個不會重復名稱,就像數(shù)據(jù)庫中產(chǎn)生一個唯一的數(shù)字主鍵一樣。
Name Service 已經(jīng)是 Zookeeper 內(nèi)置的功能,你只要調(diào)用 Zookeeper 的 API 就能實現(xiàn)。如調(diào)用 create 接口就可以很容易創(chuàng)建一個目錄節(jié)點。
案例:有一組服務(wù)器向客戶端提供某種服務(wù)(例如:使用LVS技術(shù)構(gòu)建的Web網(wǎng)站集群,就是由N臺服務(wù)器組成的集群,為用戶提供Web服務(wù))。對于這種場景,我們的程序中一定有一份這組服務(wù)器的列表,每次客戶端請求時候,都是從這份列表里讀取這份服務(wù)器列表。那么這分列表顯然不能存儲在一臺單節(jié)點的服務(wù)器上,否則這個節(jié)點掛掉了,整個集群都會發(fā)生故障,我們希望這份列表時高可用的。高可用的解決方案是:這份列表是分布式存儲的,它是由存儲這份列表的服務(wù)器共同管理的,如果存儲列表里的某臺服務(wù)器壞掉了,其他服務(wù)器馬上可以替代壞掉的服務(wù)器,并且可以把壞掉的服務(wù)器從列表里刪除掉,讓故障服務(wù)器退出整個集群的運行,而這一切的操作又不會由故障的服務(wù)器來操作,而是集群里正常的服務(wù)器來完成。這是一種主動的分布式數(shù)據(jù)結(jié)構(gòu),能夠在外部情況發(fā)生變化時候主動修改數(shù)據(jù)項狀態(tài)的數(shù)據(jù)機構(gòu)。
(2)分布式鎖服務(wù)
共享鎖在同一個進程中很容易實現(xiàn),但是在跨進程或者在不同 Server 之間就不好實現(xiàn)了。Zookeeper 卻很容易實現(xiàn)這個功能,實現(xiàn)方式也是需要獲得鎖的 Server 創(chuàng)建一個 EPHEMERAL_SEQUENTIAL 目錄節(jié)點,然后調(diào)用 getChildren方法獲取當前的目錄節(jié)點列表中最小的目錄節(jié)點是不是就是自己創(chuàng)建的目錄節(jié)點,如果正是自己創(chuàng)建的,那么它就獲得了這個鎖,如果不是那么它就調(diào)用exists(String path, boolean watch) 方法并監(jiān)控 Zookeeper 上目錄節(jié)點列表的變化,一直到自己創(chuàng)建的節(jié)點是列表中最小編號的目錄節(jié)點,從而獲得鎖,釋放鎖很簡單,只要刪除前面它自己所創(chuàng)建的目錄節(jié)點就行了。
具體步驟如下:
加鎖: ZooKeeper 將按照如下方式實現(xiàn)加鎖的操作:
1 ) ZooKeeper 調(diào)用 create ()方法來創(chuàng)建一個路徑格式為“ _locknode_/lock- ”的節(jié)點,此節(jié)點類型為sequence (連續(xù))和 ephemeral (臨時)。也就是說,創(chuàng)建的節(jié)點為臨時節(jié)點,并且所有的節(jié)點連續(xù)編號,即“ lock-i ”的格式。
2 )在創(chuàng)建的鎖節(jié)點上調(diào)用 getChildren ()方法,來獲取鎖目錄下的最小編號節(jié)點,并且不設(shè)置 watch 。
3 )步驟 2 中獲取的節(jié)點恰好是步驟 1 中客戶端創(chuàng)建的節(jié)點,那么此客戶端獲得此種類型的鎖,然后退出操作。
4 )客戶端在鎖目錄上調(diào)用 exists ()方法,并且設(shè)置 watch 來監(jiān)視鎖目錄下比自己小一個的連續(xù)臨時節(jié)點的狀態(tài)。
5 )如果監(jiān)視節(jié)點狀態(tài)發(fā)生變化,則跳轉(zhuǎn)到第 2 步,繼續(xù)進行后續(xù)的操作,直到退出鎖競爭。
解鎖:
ZooKeeper 解鎖操作非常簡單,客戶端只需要將加鎖操作步驟 1 中創(chuàng)建的臨時節(jié)點刪除即可。
void getLock() throws KeeperException, InterruptedException{ Listlist = zk.getChildren(root, false); String[] nodes = list.toArray(new String[list.size()]); Arrays.sort(nodes); if(myZnode.equals(root+"/"+nodes[0])){ doAction(); } else{ waitForLock(nodes[0]); } } void waitForLock(String lower) throws InterruptedException, KeeperException { Stat stat = zk.exists(root + "/" + lower,true); if(stat != null){ mutex.wait(); } else{ getLock(); } }
(3)配置管理(數(shù)據(jù)發(fā)布與訂閱)
在分布式系統(tǒng)里,我們會把一個服務(wù)應用分別部署到n臺服務(wù)器上,這些服務(wù)器的配置文件是相同的,如果配置文件的配置選項發(fā)生變化,那么我們就得一個個去改這些配置文件,如果我們需要改的服務(wù)器比較少,這些操作還不是太麻煩,如果我們分布式的服務(wù)器特別多,那么更改配置選項就是一件麻煩而且危險的事情。這時我們可以將配置信息保存在 Zookeeper 的某個目錄節(jié)點中,然后將所有需要修改的應用機器監(jiān)控配置信息的狀態(tài),一旦配置信息發(fā)生變化,每臺應用機器就會收到 Zookeeper 的通知,然后從 Zookeeper 獲取新的配置信息應用到系統(tǒng)中。
(4)集群管理
Zookeeper 能夠很容易的實現(xiàn)集群管理的功能,如有多臺 Server 組成一個服務(wù)集群,那么必須要一個“總管”知道當前集群中每臺機器的服務(wù)狀態(tài),一旦有機器不能提供服務(wù),集群中其它集群必須知道,從而做出調(diào)整重新分配服務(wù)策略。同樣當增加集群的服務(wù)能力時,就會增加一臺或多臺 Server,同樣也必須讓“總管”知道。
Zookeeper 不僅能夠幫你維護當前的集群中機器的服務(wù)狀態(tài),而且能夠幫你選出一個“總管”,讓這個總管來管理集群,這就是 Zookeeper 的另一個功能 Leader Election。
它們的實現(xiàn)方式都是在 Zookeeper 上創(chuàng)建一個 EPHEMERAL 類型的目錄節(jié)點,然后每個 Server 在它們創(chuàng)建目錄節(jié)點的父目錄節(jié)點上調(diào)用 getChildren(String path, boolean watch) 方法并設(shè)置 watch 為 true,由于是 EPHEMERAL 目錄節(jié)點,當創(chuàng)建它的 Server 死去,這個目錄節(jié)點也隨之被刪除,所以 Children 將會變化,這時 getChildren上的 Watch 將會被調(diào)用,所以其它 Server 就知道已經(jīng)有某臺 Server 死去了。新增 Server 也是同樣的原理。
Zookeeper 如何實現(xiàn) Leader Election,也就是選出一個 Master Server。和前面的一樣每臺 Server 創(chuàng)建一個 EPHEMERAL 目錄節(jié)點,不同的是它還是一個 SEQUENTIAL 目錄節(jié)點,所以它是個 EPHEMERAL_SEQUENTIAL 目錄節(jié)點。之所以它是 EPHEMERAL_SEQUENTIAL 目錄節(jié)點,是因為我們可以給每臺 Server 編號,我們可以選擇當前是最小編號的 Server 為 Master,假如這個最小編號的 Server 死去,由于是 EPHEMERAL 節(jié)點,死去的 Server 對應的節(jié)點也被刪除,所以當前的節(jié)點列表中又出現(xiàn)一個最小編號的節(jié)點,我們就選擇這個節(jié)點為當前 Master。這樣就實現(xiàn)了動態(tài)選擇 Master,避免了傳統(tǒng)意義上單 Master 容易出現(xiàn)單點故障的問題。
PS:關(guān)于Master的選舉,可以參考:http://www.cnblogs.com/sundde...。
注意:ZooKeeper所提供的服務(wù)主要是通過:數(shù)據(jù)結(jié)構(gòu)+原語(一些關(guān)于該數(shù)據(jù)結(jié)構(gòu)的一些操作)+watcher機制,三個部分來實現(xiàn)的
(5)、隊列管理
Zookeeper 可以處理兩種類型的隊列:
當一個隊列的成員都聚齊時,這個隊列才可用,否則一直等待所有成員到達,這種是同步隊列。
隊列按照 FIFO 方式進行入隊和出隊操作,例如實現(xiàn)生產(chǎn)者和消費者模型。
A、同步隊列 用 Zookeeper 實現(xiàn)的實現(xiàn)思路如下:
創(chuàng)建一個父目錄 /synchronizing,每個成員都監(jiān)控標志(Set Watch)位目錄 /synchronizing/start 是否存在,然后每個成員都加入這個隊列,加入隊列的方式就是創(chuàng)建 /synchronizing/member_i 的臨時目錄節(jié)點,然后每個成員獲取 / synchronizing 目錄的所有目錄節(jié)點,也就是 member_i。判斷 i 的值是否已經(jīng)是成員的個數(shù),如果小于成員個數(shù)等待 /synchronizing/start 的出現(xiàn),如果已經(jīng)相等就創(chuàng)建 /synchronizing/start。
void addQueue() throws KeeperException, InterruptedException{ zk.exists(root + "/start",true); zk.create(root + "/" + name, new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL); synchronized (mutex) { Listlist = zk.getChildren(root, false); if (list.size() < size) { mutex.wait(); } else { zk.create(root + "/start", new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT); } } } public void process(WatchedEvent event) { if(event.getPath().equals(root + "/start") && event.getType() == Event.EventType.NodeCreated){ System.out.println("得到通知"); super.process(event); doAction(); } }
B、FIFO隊列:
實現(xiàn)的思路也非常簡單,就是在特定的目錄下創(chuàng)建 SEQUENTIAL 類型的子目錄 /queue_i,這樣就能保證所有成員加入隊列時都是有編號的,出隊列時通過 getChildren( ) 方法可以返回當前所有的隊列中的元素,然后消費其中最小的一個,這樣就能保證 FIFO。
boolean produce(int i) throws KeeperException, InterruptedException{ ByteBuffer b = ByteBuffer.allocate(4); byte[] value; b.putInt(i); value = b.array(); zk.create(root + "/element", value, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT_SEQUENTIAL); return true; } int consume() throws KeeperException, InterruptedException{ int retvalue = -1; Stat stat = null; while (true) { synchronized (mutex) { ListZooKeeper集群模式搭建list = zk.getChildren(root, true); if (list.size() == 0) { mutex.wait(); } else { Integer min = new Integer(list.get(0).substring(7)); for(String s : list){ Integer tempValue = new Integer(s.substring(7)); if(tempValue < min) min = tempValue; } byte[] b = zk.getData(root + "/element" + min,false, stat); zk.delete(root + "/element" + min, 0); ByteBuffer buffer = ByteBuffer.wrap(b); retvalue = buffer.getInt(); return retvalue; } } } }
注意:ZooKeeper服務(wù)器集群規(guī)模不小于3個節(jié)點,要求各服務(wù)器之間系統(tǒng)時間要保持一致;
1、下載解壓安裝后,修改環(huán)境變量:vim /etc/profile
增加一行:export ZOOKEEPER_HOME=/usr/local/zookeeper
修改PATH:export PATH=.:$HADOOP_HOME/bin:$ZOOKEEPER_HOME/bin:$JAVA_HOME/bin:$PATH
使配置生效:source /etc/profile
2、進入zookeeper的conf目錄下,修改文件名:mv zoo_sample.cfg zoo.cfg
編輯zoo.cfg:vim zoo.cfg
修改dataDir=/usr/local/zookeeper/data
新增
server.0=hadoop-master:2888:3888
server.1=hadoop-slave1:2888:3888
server.2=hadoop-slave2:2888:3888
3、創(chuàng)建data文件夾,并創(chuàng)建myid文件:
新建data文件夾:mkdir /usr/local/zookeeper/data
新建myid文件:vim myid,并設(shè)置第一臺server為0。
4、復制zookeeper目錄至其余兩臺服務(wù)器中:
scp /usr/local/zookeeper hadoop-slave1:/usr/local/
scp /usr/local/zookeeper hadoop-slave2:/usr/local/
5、復制環(huán)境變量配置文件至其余兩臺服務(wù)器中:
scp /etc/profile hadoop-slave1:/etc
scp /etc/profile hadoop-slave2:/etc
6、在其余兩臺服務(wù)器中修改myid文件:設(shè)置為1和2;
7、啟動ZooKeeper,分別在三個節(jié)點中執(zhí)行命令:zkServer.sh start
8、檢驗ZooKeeper集群節(jié)點角色狀態(tài),分別在三個節(jié)點中執(zhí)行命令:zkServer.sh status (可以看出哪個節(jié)點是leader,follower,observer等)
ZooKeeper中包含以下角色:
領(lǐng)導者(leader),負責進行投票的發(fā)起和決議,更新系統(tǒng)狀態(tài);
學習者(learner),包括跟隨者(follower)和觀察者(observer),follower用于接受客戶端請求并向客戶端返回結(jié)果,在選主過程中參與投票;observer可以接受客戶端連接,將寫請求轉(zhuǎn)發(fā)給leader,但observer不參加投票過程,只同步leader的狀態(tài),observer的目的是為了擴展系統(tǒng),提高讀取速度;
9、ZooKeeper簡單測試
搭建好集群環(huán)境后,就可以進行簡單的讀寫一致性測試了,這里我們通過進入zookeeper的bin目錄下的zkCli.sh來完成下面的操作:
(1)在其中一個節(jié)點192.168.80.100上執(zhí)行一個寫操作:create /MyTest test
(2)在其他兩個節(jié)點上執(zhí)行讀操作:get /MyTest
TIP:可以在一個節(jié)點中通過zkCli.sh -server hadoop-slave1:2181來遠程登錄
(3)在其中一個節(jié)點192.168.80.101上執(zhí)行一個修改操作:set /MyTest new-test ,在其他兩個節(jié)點上執(zhí)行讀操作查看數(shù)據(jù)是否一致
[zkshell: 0] help ZooKeeper host:port cmd args get path [watch] ls path [watch] set path data [version] delquota [-n|-b] path quit printwatches on|off createpath data acl stat path [watch] listquota path history setAcl path acl getAcl path sync path redo cmdno addauth scheme auth delete path [version] setquota -n|-b val path編程
APIDOC: https://zookeeper.apache.org/...
org.apache.zookeeper zookeeper 3.4.6
Zookeeper主要用來解決分布式集群中應用系統(tǒng)的一致性問題,它能提供基于類似于文件系統(tǒng)的目錄節(jié)點樹方式的數(shù)據(jù)存儲,但是 Zookeeper 并不是用來專門存儲數(shù)據(jù)的,它的作用主要是用來維護和監(jiān)控你存儲的數(shù)據(jù)的狀態(tài)變化。通過監(jiān)控這些數(shù)據(jù)狀態(tài)的變化,從而可以達到基于數(shù)據(jù)的集群管理
客戶端要連接 Zookeeper 服務(wù)器可以通過創(chuàng)建 org.apache.zookeeper.ZooKeeper 的一個實例對象,然后調(diào)用這個類提供的接口來和服務(wù)器交互。
前面說了 ZooKeeper 主要是用來維護和監(jiān)控一個目錄節(jié)點樹中存儲的數(shù)據(jù)的狀態(tài),所有我們能夠操作 ZooKeeper 的也和操作目錄節(jié)點樹大體一樣,如創(chuàng)建一個目錄節(jié)點,給某個目錄節(jié)點設(shè)置數(shù)據(jù),獲取某個目錄節(jié)點的所有子目錄節(jié)點,給某個目錄節(jié)點設(shè)置權(quán)限和監(jiān)控這個目錄節(jié)點的狀態(tài)變化。
常見方法:
String create(String path, byte[] data, List
CreateMode 標識有四種形式的目錄節(jié)點:
PERSISTENT:持久化目錄節(jié)點,這個目錄節(jié)點存儲的數(shù)據(jù)不會丟失;
PERSISTENT_SEQUENTIAL:順序自動編號的目錄節(jié)點,這種目錄節(jié)點會根據(jù)當前已近存在的節(jié)點數(shù)自動加 1,然后返回給客戶端已經(jīng)成功創(chuàng)建的目錄節(jié)點名;
EPHEMERAL:臨時目錄節(jié)點,一旦創(chuàng)建這個節(jié)點的客戶端與服務(wù)器端口也就是 session 超時,這種節(jié)點會被自動刪除;
EPHEMERAL_SEQUENTIAL:臨時自動編號節(jié)點
Stat exists(String path, boolean watch) 判斷某個 path 是否存在,并設(shè)置是否監(jiān)控這個目錄節(jié)點,這里的 watcher 是在創(chuàng)建 ZooKeeper 實例時指定的 watcher
Stat exists(String path,Watcher watcher) 重載方法,這里給某個目錄節(jié)點設(shè)置特定的 watcher,Watcher 在 ZooKeeper 是一個核心功能,Watcher 可以監(jiān)控目錄節(jié)點的數(shù)據(jù)變化以及子目錄的變化,一旦這些狀態(tài)發(fā)生變化,服務(wù)器就會通知所有設(shè)置在這個目錄節(jié)點上的 Watcher,從而每個客戶端都很快知道它所關(guān)注的目錄節(jié)點的狀態(tài)發(fā)生變化,而做出相應的反應
void delete(String path, int version) 刪除 path 對應的目錄節(jié)點,version 為 -1 可以匹配任何版本,也就刪除了這個目錄節(jié)點所有數(shù)據(jù)
List
Stat setData(String path, byte[] data, int version) 給 path 設(shè)置數(shù)據(jù),可以指定這個數(shù)據(jù)的版本號,如果 version 為 -1 怎可以匹配任何版本
byte[] getData(String path, boolean watch, Stat stat) 獲取這個 path 對應的目錄節(jié)點存儲的數(shù)據(jù),數(shù)據(jù)的版本等信息可以通過 stat 來指定,同時還可以設(shè)置是否監(jiān)控這個目錄節(jié)點數(shù)據(jù)的狀態(tài)
void addAuthInfo(String scheme, byte[] auth) 客戶端將自己的授權(quán)信息提交給服務(wù)器,服務(wù)器將根據(jù)這個授權(quán)信息驗證客戶端的訪問權(quán)限。
Stat setACL(String path,List
Perms 有 ALL、READ、WRITE、CREATE、DELETE、ADMIN 幾種,而 id 標識了訪問目錄節(jié)點的身份列表,默認情況下有以下兩種:ANYONE_ID_UNSAFE = new Id("world", "anyone") 和 AUTH_IDS = new Id("auth", "") 分別表示任何人都可以訪問和創(chuàng)建者擁有訪問權(quán)限。
List
// 創(chuàng)建一個與服務(wù)器的連接 ZooKeeper zk = new ZooKeeper("localhost:" + CLIENT_PORT, ClientBase.CONNECTION_TIMEOUT, new Watcher() { // 監(jiān)控所有被觸發(fā)的事件 public void process(WatchedEvent event) { System.out.println("已經(jīng)觸發(fā)了" + event.getType() + "事件!"); } }); // 創(chuàng)建一個目錄節(jié)點 zk.create("/testRootPath", "testRootData".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT); // 創(chuàng)建一個子目錄節(jié)點 zk.create("/testRootPath/testChildPathOne", "testChildDataOne".getBytes(), Ids.OPEN_ACL_UNSAFE,CreateMode.PERSISTENT); System.out.println(new String(zk.getData("/testRootPath",false,null))); // 取出子目錄節(jié)點列表 System.out.println(zk.getChildren("/testRootPath",true)); // 修改子目錄節(jié)點數(shù)據(jù) zk.setData("/testRootPath/testChildPathOne","modifyChildDataOne".getBytes(),-1); System.out.println("目錄節(jié)點狀態(tài):["+zk.exists("/testRootPath",true)+"]"); // 創(chuàng)建另外一個子目錄節(jié)點 zk.create("/testRootPath/testChildPathTwo", "testChildDataTwo".getBytes(), Ids.OPEN_ACL_UNSAFE,CreateMode.PERSISTENT); System.out.println(new String(zk.getData("/testRootPath/testChildPathTwo",true,null))); // 刪除子目錄節(jié)點 zk.delete("/testRootPath/testChildPathTwo",-1); zk.delete("/testRootPath/testChildPathOne",-1); // 刪除父目錄節(jié)點 zk.delete("/testRootPath",-1); // 關(guān)閉連接 zk.close();
官網(wǎng)例子請看:http://zookeeper.majunwei.com...
其他例子:
http://www.uml.org.cn/zjjs/20...
http://www.uml.org.cn/zjjs/20...
http://zookeeper.majunwei.com...
參考:官方文檔:https://zookeeper.apache.org/...
小馬過河翻譯社,Zookeeper文檔中文版:http://zookeeper.majunwei.com...
周旭龍,ZooKeeper環(huán)境搭建:http://www.cnblogs.com/edison...
Zookeeper 的學習與運用:http://www.oschina.net/questi...
鄔興亮,Zookeeper隨筆系列:http://www.cnblogs.com/wuxl36...
ggjucheng,Zookeeper Api(java)入門與應用:http://www.cnblogs.com/ggjuch...
其他推薦:
http://cailin.iteye.com/blog/...
http://www.uml.org.cn/wenzhan...
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/67377.html
摘要:相關(guān)概念協(xié)議高級消息隊列協(xié)議是一個標準開放的應用層的消息中間件協(xié)議??梢杂妹钆c不同,不是線程安全的。手動提交執(zhí)行相關(guān)邏輯提交注意點將寫成單例模式,有助于減少端占用的資源。自身是線程安全的類,只要封裝得當就能最恰當?shù)陌l(fā)揮好的作用。 本文使用的Kafka版本0.11 先思考些問題: 我想分析一下用戶行為(pageviews),以便我能設(shè)計出更好的廣告位 我想對用戶的搜索關(guān)鍵詞進行統(tǒng)計,...
摘要:在的的首次會議慶祝了其新功能版本的發(fā)布??梢砸赃@三種方式暴露出來內(nèi)部外部和負載均衡。比如,可能會通過一個彈性負載均衡器接收流量,或者通過谷歌的負載均衡器接收。這個功能令第三方負載均衡器整合到。負起了接管發(fā)現(xiàn)任務(wù)和微服務(wù)負載均衡器的重任。 隨著容器逐漸受到企業(yè)的注意,焦點慢慢被轉(zhuǎn)移到了容器編排工具上。復雜的工作負載在生產(chǎn)過程中需要成熟地被調(diào)度,編排,彈性擴容和管理工具。有了Docker,...
摘要:同時集成了機器學習類庫?;谟嬎憧蚣埽瑢⒌姆植际接嬎銘玫綑C器學習領(lǐng)域。提供了一個簡單的聲明方法指定機器學習任務(wù),并且動態(tài)地選擇最優(yōu)的學習算法。宣稱其性能是的多倍。 介紹 spark是分布式并行數(shù)據(jù)處理框架 與mapreduce的區(qū)別: mapreduce通常將中間結(jié)果放在hdfs上,spark是基于內(nèi)存并行大數(shù)據(jù)框架,中間結(jié)果放在內(nèi)存,對于迭代數(shù)據(jù)spark效率更高,mapred...
摘要:作為面試官,我是如何甄別應聘者的包裝程度語言和等其他語言的對比分析和主從復制的原理詳解和持久化的原理是什么面試中經(jīng)常被問到的持久化與恢復實現(xiàn)故障恢復自動化詳解哨兵技術(shù)查漏補缺最易錯過的技術(shù)要點大掃盲意外宕機不難解決,但你真的懂數(shù)據(jù)恢復嗎每秒 作為面試官,我是如何甄別應聘者的包裝程度Go語言和Java、python等其他語言的對比分析 Redis和MySQL Redis:主從復制的原理詳...
閱讀 1045·2023-04-26 01:47
閱讀 1709·2021-11-18 13:19
閱讀 2074·2019-08-30 15:44
閱讀 682·2019-08-30 15:44
閱讀 2340·2019-08-30 15:44
閱讀 1265·2019-08-30 14:06
閱讀 1444·2019-08-30 12:59
閱讀 1919·2019-08-29 12:49