最新文章專題視頻專題問答1問答10問答100問答1000問答2000關鍵字專題1關鍵字專題50關鍵字專題500關鍵字專題1500TAG最新視頻文章推薦1 推薦3 推薦5 推薦7 推薦9 推薦11 推薦13 推薦15 推薦17 推薦19 推薦21 推薦23 推薦25 推薦27 推薦29 推薦31 推薦33 推薦35 推薦37視頻文章20視頻文章30視頻文章40視頻文章50視頻文章60 視頻文章70視頻文章80視頻文章90視頻文章100視頻文章120視頻文章140 視頻2關鍵字專題關鍵字專題tag2tag3文章專題文章專題2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章專題3
問答文章1 問答文章501 問答文章1001 問答文章1501 問答文章2001 問答文章2501 問答文章3001 問答文章3501 問答文章4001 問答文章4501 問答文章5001 問答文章5501 問答文章6001 問答文章6501 問答文章7001 問答文章7501 問答文章8001 問答文章8501 問答文章9001 問答文章9501
當前位置: 首頁 - 科技 - 知識百科 - 正文

ZooKeeperNote–常用操作和應用

來源:懂視網(wǎng) 責編:小采 時間:2020-11-09 13:03:50
文檔

ZooKeeperNote–常用操作和應用

ZooKeeperNote–常用操作和應用:ZooKeeper是一個用于分布式應用程序的分布式開源協(xié)調服務。它使用一組簡單的操作原語,使得分布式應用可以實現(xiàn)更高層次的服務——如同步、配置維護、群組和命名管理等。ZK具有高性能、高可用(復制)、有序等特征。請參考上一篇譯文zookeeper:一個用于分布
推薦度:
導讀ZooKeeperNote–常用操作和應用:ZooKeeper是一個用于分布式應用程序的分布式開源協(xié)調服務。它使用一組簡單的操作原語,使得分布式應用可以實現(xiàn)更高層次的服務——如同步、配置維護、群組和命名管理等。ZK具有高性能、高可用(復制)、有序等特征。請參考上一篇譯文zookeeper:一個用于分布

ZooKeeper是一個用于分布式應用程序的分布式開源協(xié)調服務。它使用一組簡單的操作原語,使得分布式應用可以實現(xiàn)更高層次的服務——如同步、配置維護、群組和命名管理等。ZK具有高性能、高可用(復制)、有序等特征。請參考上一篇譯文zookeeper:一個用于分布

ZooKeeper是一個用于分布式應用程序的分布式開源協(xié)調服務。它使用一組簡單的操作原語,使得分布式應用可以實現(xiàn)更高層次的服務——如同步、配置維護、群組和命名管理等。ZK具有高性能、高可用(復制)、有序等特征。請參考上一篇譯文zookeeper:一個用于分布式應用的分布式協(xié)調服務。本文簡單介紹一下開發(fā)中經(jīng)常使用的方法(文檔:ZooKeeper API)。

1. create

Class:org.apache.zookeeper.ZooKeeper
public String create(String path, byte[] data, List acl, CreateMode createMode) throws KeeperException, InterruptedException
public void create(String path, byte[] data, List acl, CreateMode createMode, AsyncCallback.StringCallback cb, Object ctx)
創(chuàng)建一個給定路徑(path)的節(jié)點,并給它設置數(shù)據(jù)(data)和訪問控制列表(acl)。ZooKeeper中的節(jié)點相對于文件系統(tǒng)中的目錄結構,即是”directory”又是”regular file”。第二個create方法是create的異步版本,當創(chuàng)建完成時則調用異步callback。

(1). org.apache.zookeeper.data.ACL

這部分節(jié)選說說Zookeeper中的ACL
ZooKeeper通過ACL來對ZNode進行訪問控制。ZooKeeper客戶端為znode指定ACL列表,ZooKeeper服務器根據(jù)ACL列表判定某個請求ZNode的客戶端是否有對應操作的權限。
一個ACL對象由schema:ID和Permissions組成。
a). scheme: scheme對應于采用哪種方案來進行權限管理,zookeeper實現(xiàn)了一個pluggable的ACL方案,可以通過擴展scheme,來擴展ACL的機制。zookeeper-3.4.4缺省支持下面幾種scheme:
world: 它下面只有一個id, 叫anyone, world:anyone代表任何人,zookeeper中對所有人有權限的結點就是屬于world:anyone的
auth: 它不需要id, 只要是通過authentication的user都有權限(zookeeper支持通過kerberos來進行authencation, 也支持username/password形式的authentication)
digest: 它對應的id為username:BASE64(SHA1(password)),它需要先通過username:password形式的authentication
ip: 它對應的id為客戶機的IP地址,設置的時候可以設置一個ip段,比如ip:192.168.1.0/16, 表示匹配前16個bit的IP段
super: 在這種scheme情況下,對應的id擁有超級權限,可以做任何事情(cdrwa)
b). perm. ZooKeeper中有5種權限,從低位到高位分別是READ、WRITE、CREATE、DELETE和ADMIN,ACL的Permissions可以是5種權限中的1種或多種,它們的含義是:
* READ: 允許獲取該節(jié)點的值和列出子節(jié)點。
* WRITE: 允許設置該節(jié)點的值。
* CREATE: 允許創(chuàng)建子節(jié)點。
* DELETE: 可以刪除子節(jié)點。
* ADMIN: 允許為該節(jié)點設置權限。

(2). org.apache.zookeeper.CreateMode

org.apache.zookeeper.CreateMode可以設置znode是否為EPHEMERAL或者SEQUENTIAL。可以為下面四種值:
PERSISTENT 持久化目錄znode
PERSISTENT_SEQUENTIAL 順序自動編號的目錄znode。這個目錄節(jié)點是根據(jù)當前已存在的節(jié)點數(shù)遞增。
EPHEMERAL 臨時目錄znode,一旦創(chuàng)建這個znode的客戶端和服務器斷開,這個節(jié)點就會自動刪除。臨時節(jié)點(EPHEMERAL)不能有子節(jié)點數(shù)據(jù)
EPHEMERAL_SEQUENTIAL 臨時自動編號znode。

(3). zkCli命令

在zkCli中實現(xiàn)了create的命令封裝,可以用戶測試和數(shù)據(jù)管理:
create [-s] [-e] path data acl
其中”-s”表示創(chuàng)建一個順序自動編號的節(jié)點,”-e”表示創(chuàng)建一個臨時節(jié)點.默認為持久性節(jié)點
例如:
創(chuàng)建一個永久節(jié)點和臨時節(jié)點

create /test null
Created /test
create -e /test0 null
Created /test0

創(chuàng)建一個順序自動編號的節(jié)點,ACL為使用digest(用戶名:test 密碼:debugo),權限為所有(rwcda)。關于digest的產(chǎn)生,可以參考zookeeper中 DigestAuthenticationProvider.generateDigest(String ipName)方法;通過向此方法指定原始的用戶名和密碼即可獲得”digest”之后的字符串,比如傳入”test:test”,將會得 到”test:V28q/NynI4JI3Rk54h0r8O5kMug=”,其內部原理是將”密碼”部分進行MD5 + sha1操作.

create -s /test0/test null digest:test:V28q/NynI4JI3Rk54h0r8O5kMug=:rwcda
Ephemerals cannot have children: /test0/test
create -s /test/test null digest:test:V28q/NynI4JI3Rk54h0r8O5kMug=:rwcda
Created /test/test0000000000

創(chuàng)建一個節(jié)點,其ACL使用ip(172.19.17.0/24)只具有讀權限

create /test/test1 "hello world" ip:172.19.17.0/24:r
Created /test/test1

2. exist

class:org.apache.zookeeper.ZooKeeper
public Stat exists(String path, Watcher watcher) throws KeeperException, InterruptedException
返回某個path的znode是否存在。并設置是否監(jiān)控這個節(jié)點(第二個參數(shù)boolean watcher)。當?shù)诙€參數(shù)為true且這個語句執(zhí)行成功時,監(jiān)聽器(watcher)就會在成功執(zhí)行建立節(jié)點/刪除節(jié)點/修改該節(jié)點數(shù)據(jù)時候被觸發(fā)。
exists(String, Watcher)
重載方法,這里可以指定特定的監(jiān)聽器(watcher)對象。
exists(String, Watcher, AsyncCallback.StatCallback, Object)
exists(String, boolean, AsyncCallback.StatCallback, Object)
exist的異步實現(xiàn)

3. delete

public void delete(String path, int version) throws InterruptedException, KeeperException
刪除path對應的znode,version為-1可以匹配任何版本,也就是刪除這個節(jié)點所有的數(shù)據(jù)。此外,delete同樣存在異步版本。
delete(String path, int version, AsyncCallback.VoidCallback cb, Object ctx)
delete的異步版本。
例如zkCli中刪除某個節(jié)點:

delete /test/test1

4. getChildren

public List getChildren(String path, boolean watch) throws KeeperException, InterruptedException
獲取指定path下所有的子znode,這個方法和exist一樣同樣可以設置watcher/指定特定的Watcher對象。

5. setData & getData

Stat setData(String path, byte[] data, int version)
當給定path的節(jié)點存在時給path設置數(shù)據(jù),可以指定這個數(shù)據(jù)的版本號。如果version為-1則可以匹配任意版本。
void setData(String path, byte[] data, int version, AsyncCallback.StatCallback cb, Object ctx)
setData的異步版本。
byte[] getData(String path, Watcher watcher, Stat stat)
獲取這個path對應的znode節(jié)點的數(shù)據(jù),數(shù)據(jù)的版本等信息可以通過stat來指定。
void getData(String path, Watcher watcher, AsyncCallback.DataCallback cb, Object ctx)
getData的異步版本。

6. setACL和getACL

Stat setACL(String path, List acl, int version)
給某個znode節(jié)點重新設置訪問權限,需要注意的是ZooKeeper中的目錄節(jié)點權限都不具有傳遞性,父znode節(jié)點的權限不能傳遞給子目錄節(jié)點。在create中已經(jīng)介紹了ACL的設置方法,可以設置一系列ACL規(guī)則(即指定一系列ACL對象)。
void setACL(String path, List acl, int version, AsyncCallback.StatCallback cb, Object ctx)
setACL的異步版本
List getACL(String path, Stat stat)
返回某個znode節(jié)點的ACL對象的列表。
void getACL(String path, Stat stat, AsyncCallback.ACLCallback cb, Object ctx)
getACL的異步版本
例如zkCli中設置某個ACL規(guī)則:

[zk: localhost:2181(CONNECTED) 43] setAcl /test world:anyone:r
cZxid = 0xf000500ed
ctime = Wed Sep 24 15:13:29 CST 2014
......
[zk: localhost:2181(CONNECTED) 44] getAcl /test
'world,'anyone
: r

下面的內容來自分布式服務框架 Zookeeper — 管理分布式環(huán)境中的數(shù)據(jù),寫得很不錯,摘過來僅留作自己參考^^。
Zookeeper從設計模式角度來看,是一個基于觀察者模式設計的分布式服務管理框架,它負責存儲和管理大家都關心的數(shù)據(jù),然后接受觀察者的注冊,一旦這些數(shù)據(jù)的狀態(tài)發(fā)生變化,Zookeeper就將負責通知已經(jīng)在Zookeeper上注冊的那些觀察者做出相應的反應,從而實現(xiàn)集群中類似Master/Slave管理模式。
ZooKeeper中有下面的應用:
統(tǒng)一命名服務(NameService)
配置管理(ConfigurationManagement)
集群管理(GroupMembership)
共享鎖(Locks)
隊列管理

1. 統(tǒng)一命名服務(NameService)

分布式應用中,通常需要有一套完整的命名規(guī)則,既能夠產(chǎn)生唯一的名稱又便于人識別和記住,通常情況下用樹形的名稱結構是一個理想的選擇,樹形的名稱結構是一個有層次的目錄結構,既對人友好又不會重復。說到這里你可能想到了 JNDI,沒錯 Zookeeper 的 Name Service 與 JNDI 能夠完成的功能是差不多的,它們都是將有層次的目錄結構關聯(lián)到一定資源上,但是Zookeeper的 NameService 更加是廣泛意義上的關聯(lián),也許你并不需要將名稱關聯(lián)到特定資源上,你可能只需要一個不會重復名稱,就像數(shù)據(jù)庫中產(chǎn)生一個唯一的數(shù)字主鍵一樣。
NameService 已經(jīng)是 Zookeeper內置的功能,你只要調用Zookeeper的 API 就能實現(xiàn)。如調用create接口就可以很容易創(chuàng)建一個目錄節(jié)點。

2. 配置管理(ConfigurationManagement)

配置的管理在分布式應用環(huán)境中很常見,例如同一個應用系統(tǒng)需要多臺PCServer 運行,但是它們運行的應用系統(tǒng)的某些配置項是相同的,如果要修改這些相同的配置項,那么就必須同時修改每臺運行這個應用系統(tǒng)的PCServer,這樣非常麻煩而且容易出錯。像這樣的配置信息完全可以交給Zookeeper來管理,將配置信息保存在Zookeeper的某個目錄節(jié)點中,然后將所有需要修改的應用機器監(jiān)控配置信息的狀態(tài),一旦配置信息發(fā)生變化,每臺應用機器就會收到Zookeeper的通知,然后從Zookeeper獲取新的配置信息應用到系統(tǒng)中。
21

3. 集群管理(GroupMembership)

Zookeeper能夠很容易的實現(xiàn)集群管理的功能,如有多臺Server組成一個服務集群,那么必須要一個“總管”知道當前集群中每臺機器的服務狀態(tài),一旦有機器不能提供服務,集群中其它集群必須知道,從而做出調整重新分配服務策略。同樣當增加集群的服務能力時,就會增加一臺或多臺 Server,同樣也必須讓“總管”知道。?Zookeeper不僅能夠幫你維護當前的集群中機器的服務狀態(tài),而且能夠幫你選出一個“總管”,讓這個總管來管理集群,這就是Zookeeper的另一個功能LeaderElection。
?它們的實現(xiàn)方式都是在Zookeeper上創(chuàng)建一個EPHEMERAL類型的目錄節(jié)點,然后每個Server在它們創(chuàng)建目錄節(jié)點的父目錄節(jié)點上調用getChildren(String path,boolean watch)方法并設置watch為 true,由于是 EPHEMERAL目錄節(jié)點,當創(chuàng)建它的Server死去,這個目錄節(jié)點也隨之被刪除,所以Children將會變化,這時getChildren上的 Watch將會被調用,所以其它Server就知道已經(jīng)有某臺Server死去了。新增Server也是同樣的原理。
?Zookeeper如何實現(xiàn) LeaderElection,也就是選出一個MasterServer。和前面的一樣每臺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)單點故障的問題。
32

void findLeader() throws InterruptedException { 
 byte[] leader = null; 
 try { 
 leader = zk.getData(root + "/leader", true, null); 
 } catch (Exception e) { 
 logger.error(e); 
 } 
 if (leader != null) { 
 following(); 
 } else { 
 String newLeader = null; 
 try { 
 byte[] localhost = InetAddress.getLocalHost().getAddress(); 
 newLeader = zk.create(root + "/leader", localhost, 
 ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL); 
 } catch (Exception e) { 
 logger.error(e); 
 } 
 if (newLeader != null) { 
 leading(); 
 } else { 
 mutex.wait(); 
 } 
 } 
 }

4. 共享鎖(Locks)

共享鎖在同一個進程中很容易實現(xiàn),但是在跨進程或者在不同 Server 之間就不好實現(xiàn)了。Zookeeper 卻很容易實現(xiàn)這個功能,實現(xiàn)方式也是需要獲得鎖的 Server 創(chuàng)建一個 EPHEMERAL_SEQUENTIAL 目錄節(jié)點,然后調用 getChildren方法獲取當前的目錄節(jié)點列表中最小的目錄節(jié)點是不是就是自己創(chuàng)建的目錄節(jié)點,如果正是自己創(chuàng)建的,那么它就獲得了這個鎖,如果不是那么它就調用 exists(String path, boolean watch) 方法并監(jiān)控 Zookeeper 上目錄節(jié)點列表的變化,一直到自己創(chuàng)建的節(jié)點是列表中最小編號的目錄節(jié)點,從而獲得鎖,釋放鎖很簡單,只要刪除前面它自己所創(chuàng)建的目錄節(jié)點就行了。
41

void getLock() throws KeeperException, InterruptedException{ 
 List list = 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(); 
 } 
 }

5. 隊列管理

Zookeeper 可以處理兩種類型的隊列:
當一個隊列的成員都聚齊時,這個隊列才可用,否則一直等待所有成員到達,這種是同步隊列。
隊列按照 FIFO 方式進行入隊和出隊操作,例如實現(xiàn)生產(chǎn)者和消費者模型。
同步隊列用 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。
用下面的流程圖更容易理解:
61

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) { 
 List list = zk.getChildren(root, false); 
 if (list.size() < size) { 
 mutex.wait(); 
 } else { 
 zk.create(root + "/start", new byte[0], Ids.OPEN_ACL_UNSAFE,
 CreateMode.PERSISTENT); 
 } 
 } 
 }

當隊列沒滿是進入 wait(),然后會一直等待 Watch 的通知,Watch 的代碼如下:

public void process(WatchedEvent event) { 
 if(event.getPath().equals(root + "/start") &&
 event.getType() == Event.EventType.NodeCreated){ 
 System.out.println("得到通知"); 
 super.process(event); 
 doAction(); 
 } 
 }

FIFO 隊列用 Zookeeper 實現(xiàn)思路如下:
實現(xiàn)的思路也非常簡單,就是在特定的目錄下創(chuàng)建 SEQUENTIAL 類型的子目錄 /queue_i,這樣就能保證所有成員加入隊列時都是有編號的,出隊列時通過 getChildren( ) 方法可以返回當前所有的隊列中的元素,然后消費其中最小的一個,這樣就能保證 FIFO。
下面是生產(chǎn)者和消費者這種隊列形式的示例代碼:
生產(chǎn)者代碼

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) { 
 List 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; 
 } 
 } 
 } 
 }

^^

聲明:本網(wǎng)頁內容旨在傳播知識,若有侵權等問題請及時與本網(wǎng)聯(lián)系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

文檔

ZooKeeperNote–常用操作和應用

ZooKeeperNote–常用操作和應用:ZooKeeper是一個用于分布式應用程序的分布式開源協(xié)調服務。它使用一組簡單的操作原語,使得分布式應用可以實現(xiàn)更高層次的服務——如同步、配置維護、群組和命名管理等。ZK具有高性能、高可用(復制)、有序等特征。請參考上一篇譯文zookeeper:一個用于分布
推薦度:
標簽: 操作 常用 應用
  • 熱門焦點

最新推薦

猜你喜歡

熱門推薦

專題
Top