ZooKeeper操作(包括命令行和API的使用)
一:Zookeeper使用
?
? ? 1.客戶端腳本使用
? ? 主要命令如下:
?
? ? ? ? 1)打開客戶端
./zkCli.sh --會(huì)默認(rèn)連接本地2181端口 ./zkCli.sh -server ip:port --打開指定IP:port
 ? ? ? ? 2)添加節(jié)點(diǎn)
 ? ? ? ? 3)修改節(jié)點(diǎn)值
? ? ? ?
? 4)查看節(jié)點(diǎn)
ls path [watch] ls /zk_test --查看/zk_test的值 ls / --查看根節(jié)點(diǎn)下所有節(jié)點(diǎn)
 ? ? ? ? 5)刪除節(jié)點(diǎn)
?
?
?
? ? ? ? 注意:如果該節(jié)點(diǎn)下有子節(jié)點(diǎn),則不能刪除該節(jié)點(diǎn),需要先刪除子節(jié)點(diǎn)
?
? ? 使用JavaAPI前提條件:本人使用zookeeper3.4.11,maven管理,pom.xml如下
<!-- https://mvnrepository.com/artifact/org.apache.zookeeper/zookeeper --><dependency><groupId>org.apache.zookeeper</groupId><artifactId>zookeeper</artifactId><version>3.4.11</version></dependency><dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.15</version> <exclusions> <exclusion> <groupId>javax.jms</groupId> <artifactId>jms</artifactId> </exclusion> <exclusion> <groupId>com.sun.jdmk</groupId> <artifactId>jmxtools</artifactId> </exclusion> <exclusion> <groupId>com.sun.jmx</groupId> <artifactId>jmxri</artifactId> </exclusion> </exclusions> </dependency>? ?由于jmxtools相關(guān)jar包需要認(rèn)證,就直接exclude,用戶也可以單獨(dú)下載之后放到m2
?
? ? 2.創(chuàng)建ZooKeeper客戶端(JavaAPI)
? ? ? ? 構(gòu)造方法如下:
ZooKeeper(java.lang.String connectString, int sessionTimeout, Watcher watcher)To create a ZooKeeper client object, the application needs to pass a connection string containing a comma separated list of host:port pairs, each corresponding to a ZooKeeper server.ZooKeeper(java.lang.String connectString, int sessionTimeout, Watcher watcher, boolean canBeReadOnly)To create a ZooKeeper client object, the application needs to pass a connection string containing a comma separated list of host:port pairs, each corresponding to a ZooKeeper server.ZooKeeper(java.lang.String connectString, int sessionTimeout, Watcher watcher, long sessionId, byte[] sessionPasswd)To create a ZooKeeper client object, the application needs to pass a connection string containing a comma separated list of host:port pairs, each corresponding to a ZooKeeper server.ZooKeeper(java.lang.String connectString, int sessionTimeout, Watcher watcher, long sessionId, byte[] sessionPasswd, boolean canBeReadOnly)To create a ZooKeeper client object, the application needs to pass a connection string containing a comma separated list of host:port pairs, each corresponding to a ZooKeeper server.?
?
? ? ? ? * Watch 是一個(gè)監(jiān)控器,用于監(jiān)控zookeeper狀態(tài)變化,當(dāng)狀態(tài)變化時(shí),會(huì)回調(diào)相關(guān)方法
? ? ? ? * sessionID和sessionPasswd 分別代表會(huì)話ID和會(huì)話秘鑰,這兩個(gè)參數(shù)能夠確定一個(gè)會(huì)話
?
? ? ? ? 使用方式如下:(寫成簡單單例方式來用)
public class ZookeeperInstance {private static ZooKeeper zookeeper = null;public static final String CONNECT_STRING = "localhost:2181";public static final int SESSION_TIME_OUT = 5000;static CountDownLatch cdl = new CountDownLatch(1);public static ZooKeeper getInstance(){if(null == zookeeper){try {zookeeper = new ZooKeeper(CONNECT_STRING, SESSION_TIME_OUT, new ZookeeperWatcher());//由于zookeeper的創(chuàng)建是異步的,直接返回的并不是可用的zookeeper,狀態(tài)也是States.CONNECTING,真正連接成功后狀態(tài)變?yōu)镃ONNECTEDcdl.await();} catch (IOException e) {e.printStackTrace();} catch (InterruptedException e) {e.printStackTrace();}}return zookeeper;}//異步處理類,當(dāng)狀態(tài)變化時(shí),會(huì)回調(diào)process方法static class ZookeeperWatcher implements Watcher{@Overridepublic void process(WatchedEvent event) {System.out.println("receive watched event:" + event);if(KeeperState.SyncConnected == event.getState()){cdl.countDown();}}} }?? ? ? 注意:zookeeper的創(chuàng)建是異步的,
?
?
? ? 3.創(chuàng)建zookeeper節(jié)點(diǎn)(JavaAPI)
? ? ? ? 方法如下所示:
java.lang.String create(java.lang.String path, byte[] data, java.util.List<ACL> acl, CreateMode createMode)Create a node with the given path.void create(java.lang.String path, byte[] data, java.util.List<ACL> acl, CreateMode createMode, AsyncCallback.StringCallback cb, java.lang.Object ctx)The asynchronous version of create.?
? ? ? ? *?path 節(jié)點(diǎn)的路徑
? ? ? ? * data 節(jié)點(diǎn)的初始值
? ? ? ? * acl 節(jié)點(diǎn)的訪問控制權(quán)限設(shè)置 (用戶可使用ZooDefs.Ids下的值,可選項(xiàng)有?OPEN_ACL_UNSAFE,?CREATOR_ALL_ACL,?READ_ACL_UNSAFE)
? ? ? ? * createMode?節(jié)點(diǎn)的創(chuàng)建策略?(用戶可使用?CreateMode下的值,可選項(xiàng)有PERSISTENT ,PERSISTENT_SEQUENTIAL,?EPHEMERAL,EPHEMERAL_SEQUENTIAL?)
? ? ? ? ? ? PERSISTENT意味持久化節(jié)點(diǎn),客戶端斷開連接后,節(jié)點(diǎn)依舊存在
? ? ? ? ? ? EPHEMERAL臨時(shí)節(jié)點(diǎn),客戶端斷開連接后,節(jié)點(diǎn)就刪除
? ? ? ? ? ? SEQUENTIAL會(huì)在節(jié)點(diǎn)path后加上一個(gè)順序碼
?
? ??? ???使用方式如下:
? ??? ? 1)同步創(chuàng)建
 ?
 ? ? ???2)異步創(chuàng)建
? ? ? ? 注意:由于此時(shí)的節(jié)點(diǎn)是異步創(chuàng)建,所以需要在最后的時(shí)候加上sleep,如果直接結(jié)束,節(jié)點(diǎn)有可能還沒創(chuàng)建成功
? ? ? ? processResult中的參數(shù)rc是響應(yīng)碼(值可參考?org.apache.zookeeper.KeeperException.Code,0代表成功)
?
? ? 4.修改zookeeper節(jié)點(diǎn)值(JavaAPI)
? ? ? ? 方法如下所示:
Stat setData(java.lang.String path, byte[] data, int version)Set the data for the node of the given path if such a node exists and the given version matches the version of the node (if the given version is -1, it matches any node's versions).void setData(java.lang.String path, byte[] data, int version, AsyncCallback.StatCallback cb, java.lang.Object ctx)The asynchronous version of setData.?? ? ???使用方式如下:
Stat stat = zookeeper.setData("/z_test_p", "112211".getBytes(), 3); System.out.println("setData res:" + stat);zookeeper.setData("/z_test_p", "1111".getBytes(), 4, new AsyncCallback.StatCallback() {@Overridepublic void processResult(int rc, String path, Object ctx, Stat stat) {System.out.println("setData res:" + stat);} }, "setData");Thread.sleep(10000);?
注意:一定要設(shè)置正確的version,如果該version不存在,則會(huì)報(bào)錯(cuò);version=-1匹配節(jié)點(diǎn)所有的version
?
?
? ? 5.查看子節(jié)點(diǎn)(JavaAPI)
? ? ? ? 方法如下所示:
java.util.List<java.lang.String> getChildren(java.lang.String path, boolean watch)Return the list of the children of the node of the given path.void getChildren(java.lang.String path, boolean watch, AsyncCallback.Children2Callback cb, java.lang.Object ctx)The asynchronous version of getChildren.void getChildren(java.lang.String path, boolean watch, AsyncCallback.ChildrenCallback cb, java.lang.Object ctx)The asynchronous version of getChildren.java.util.List<java.lang.String> getChildren(java.lang.String path, boolean watch, Stat stat)For the given znode path return the stat and children list.java.util.List<java.lang.String> getChildren(java.lang.String path, Watcher watcher)Return the list of the children of the node of the given path.void getChildren(java.lang.String path, Watcher watcher, AsyncCallback.Children2Callback cb, java.lang.Object ctx)The asynchronous version of getChildren.void getChildren(java.lang.String path, Watcher watcher, AsyncCallback.ChildrenCallback cb, java.lang.Object ctx)The asynchronous version of getChildren.java.util.List<java.lang.String> getChildren(java.lang.String path, Watcher watcher, Stat stat)For the given znode path return the stat and children list.? ? ? ? 使用方式如下:
//同步 List<String> children = zookeeper.getChildren("/", true); System.out.println(Arrays.toString(children.toArray()));//異步 zookeeper.getChildren("/", true, new AsyncCallback.Children2Callback() {@Overridepublic void processResult(int rc, String path, Object ctx, List<String> children, Stat stat) {System.out.println("children:"+children);} }, "getChildren");Thread.sleep(10000);?? ? ? 注意:用戶可自定義實(shí)現(xiàn)Children2Callback接口,用于監(jiān)控當(dāng)前節(jié)點(diǎn)的子節(jié)點(diǎn)變化,如有變化,會(huì)回調(diào)processResult方法
?
?
? ??6.查看節(jié)點(diǎn)值(JavaAPI)
? ? ? ? 方法如下所示:
void getData(java.lang.String path, boolean watch, AsyncCallback.DataCallback cb, java.lang.Object ctx)The asynchronous version of getData.byte[] getData(java.lang.String path, boolean watch, Stat stat)Return the data and the stat of the node of the given path.void getData(java.lang.String path, Watcher watcher, AsyncCallback.DataCallback cb, java.lang.Object ctx)The asynchronous version of getData.byte[] getData(java.lang.String path, Watcher watcher, Stat stat)Return the data and the stat of the node of the given path.? ? ? ? 使用方式如下所示:
//同步 byte[] data = zookeeper.getData("/z_test_p", true, new Stat()); System.out.println(new String(data));//異步 zookeeper.getData("/z_test_p", true, new AsyncCallback.DataCallback() {@Overridepublic void processResult(int rc, String path, Object ctx, byte[] data, Stat stat) {System.out.println("data:" + new String(data) + ",[" + stat +"]");} }, "getData");Thread.sleep(10000);? ?? ? 注意:用戶可自定義實(shí)現(xiàn)DataCallback接口,用戶監(jiān)控當(dāng)前節(jié)點(diǎn)的值變化
?
?
? ???7.刪除節(jié)點(diǎn)(JavaAPI)
? ? ? ? 方法如下所示:
void delete(java.lang.String path, int version)Delete the node with the given path.void delete(java.lang.String path, int version, AsyncCallback.VoidCallback cb, java.lang.Object ctx)The asynchronous version of delete.? ? ? ? 使用方式如下
//直接刪除 zookeeper.delete("/z_test_asyn_p_", 0);//異步刪除 zookeeper.delete("/z_test_e", 0, new AsyncCallback.VoidCallback() {@Overridepublic void processResult(int rc, String path, Object ctx) {System.out.println("delete path result:" + rc + "," + path + "," + ctx );} }, "delete this path");Thread.sleep(10000);? ? ? ? 注意:只允許刪除葉子節(jié)點(diǎn),如果當(dāng)前節(jié)點(diǎn)還有子節(jié)點(diǎn),則無法刪除?
? ? 8.權(quán)限認(rèn)證
? ? ? ? 添加權(quán)限方法如下:
void addAuthInfo(java.lang.String scheme, byte[] auth)Add the specified scheme:auth information to this connection.? ? ? ? schema權(quán)限模式有:
? ? ? ? * ip (針對(duì)某個(gè)特定的IP)
? ? ? ? * digest (常用模式,形如 username:password)
? ? ? ? * world (開放模式,對(duì)所有用戶開放)
? ? ? ? * super (超級(jí)管理員模式,可以對(duì)任何節(jié)點(diǎn)進(jìn)行操作)
?
? ? ? ? 使用方式如下:
String path ="/act1"; CountDownLatch cdl = new CountDownLatch(1); try {//給當(dāng)前zookeeper客戶端添加權(quán)限zookeeper.addAuthInfo("digest", "zhangsan:123".getBytes());//用戶注冊(cè)模式zookeeper.create(path, "data".getBytes(), Ids.CREATOR_ACL_UNSAFE, CreateMode.PERSISTENT, new AsyncCallback.StringCallback() {@Overridepublic void processResult(int rc, String path, Object ctx, String name) {System.out.println("create path result:" + rc + "," + path + "," + ctx + ",real name :" + name); cdl.countDown();}}, "createNode");cdl.await(); } ommit ...? ? ? ? 這樣創(chuàng)建出的的節(jié)點(diǎn)/act1就除了zhangsan的其他普通用戶(admin除外)就無法進(jìn)行訪問
? ??? ??注意:ACL需要是 CREATOR_ACL_UNSAFE,表示只有該創(chuàng)建者擁有增刪改查權(quán)限
?
? ? ? ? 下面用其他客戶端訪問
//重新獲取客戶端,定義為其他用戶名密碼 ZooKeeper zookeeper1 = new ZooKeeper(ZookeeperInstance.CONNECT_STRING, ZookeeperInstance.SESSION_TIME_OUT, new ZookeeperWatcher()); zookeeper1.addAuthInfo("digest", "lisi:321".getBytes()); Thread.sleep(3000); //用其他賬戶來讀取/act數(shù)據(jù) byte[] data = zookeeper1.getData(path, true, null); System.out.println(new String(data));? ? ? ? 會(huì)報(bào)錯(cuò),KeeperErrorCode = NoAuth for /act1
 參考:
從Paxos到Zookeeper? 分布式一致性原理與實(shí)踐(倪超)
zookeeper3.4.11 API
?
總結(jié)
以上是生活随笔為你收集整理的ZooKeeper操作(包括命令行和API的使用)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
                            
                        - 上一篇: u盘启动计算机看不到硬盘,解决办法:从U
 - 下一篇: TOI2008 二元一次联立方程式