一、简介
在文章 zookeeper使用(一)--简介与安装中,我们介绍了zookeeper相关知识及安装方法。
在文本,将介绍zookeeper的常用命令,以及在java中的基本操作(包括原生的zookeeper和包装后的ZkClient)。
二、常用命令
1、启动、停止服务
./zkServer.sh start[stop]
2、连接服务
./zkCli.sh -server ip:port
3、清理历史数据、包括事务日志谁的和快照数据文件
./zkCleanup.sh
4、设置zookeeper的环境变量
./zkEnv.sh
5、创建节点
create [-s] [-e] path data acl
其中,-s指顺序节点,-e指临时节点,不添加-s和-e时,创建的是持久节点。acl是权限控制,不添加时,无权限控制。
6、查看子节点
ls path
7、获取指定节点的数据内容和属性信息
get path
8、更新节点数据内容
set path data
9、删除节点
delete path
10、递归删除节点
rmr path
三、原生zookeeper的java客户端使用
1、添加maven依赖
<dependency> <groupId>org.apache.zookeeper</groupId> <artifactId>zookeeper</artifactId> <version>3.4.6</version> </dependency>
2、代码实例
public class ZookeeperMain { public static void main(String[] args) throws Exception { String connectStr = "127.0.0.1:2181"; //连接地址,后可跟目录,如127.0.0.1:2181/mydata Watcher watcher = new SimpleWatcher(); //事件监听器 int sessionTimeout = 10000; //会话超时时间,单位是毫秒 ZooKeeper zookeeper = new ZooKeeper(connectStr,sessionTimeout,watcher); //创建会话 System.out.println("zookeeper state: "+ zookeeper.getState()); long sessionId = zookeeper.getSessionId(); //会话id ,用于重连 byte[] sessionPasswd = zookeeper.getSessionPasswd(); //会话密码,用于重连 TimeUnit.SECONDS.sleep(8); System.out.println("zookeeper state : "+zookeeper.getState()); zookeeper = new ZooKeeper(connectStr,sessionTimeout,watcher,sessionId,sessionPasswd); //重新连接 System.out.println("zookeeper state : "+zookeeper.getState()); //同步创建节点 String m1 = zookeeper.create("/m1","mv1".getBytes("utf-8"), ZooDefs.Ids.OPEN_ACL_UNSAFE,CreateMode.PERSISTENT); //异步创建节点 zookeeper.create("/m2", "mv2".getBytes("utf-8"), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT , new AsyncCallback.StringCallback() { public void processResult(int rc, String path, Object ctx, String name) { System.out.println("异步创建节点成功 rc:"+rc+ " path:"+path+" ctx:"+ctx+" name:"+name); } },"context"); //同步获取子节点 List<String> children = zookeeper.getChildren("/",watcher); System.out.println("同步获取子节点:"+children); //异步获取子节点 zookeeper.getChildren("/", watcher, new AsyncCallback.Children2Callback() { public void processResult(int rc, String path, Object ctx, List<String> children, Stat stat) { System.out.println("异步获取子节点:"+children); } },null); //同步获取节点的值 Stat stat = new Stat(); byte[] dataByte = zookeeper.getData("/m1",watcher,stat); String data = new String(dataByte,"utf-8"); System.out.println("同步获取节点的值 m1 :"+data); //异步获取节点的值 zookeeper.getData("/m1", watcher, new AsyncCallback.DataCallback() { public void processResult(int rc, String path, Object ctx, byte[] data, Stat stat) { try { System.out.println("异步获取节点的值 m1 :"+new String(data,"utf-8")); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } } },null); //同步更新值 zookeeper.setData("/m1","nm1".getBytes("utf8"),-1); //异步更新值 zookeeper.setData("/m1", "nnm1".getBytes("utf8"), -1, new AsyncCallback.StatCallback() { public void processResult(int rc, String path, Object ctx, Stat stat) { if(rc==0){ System.out.println("异步更新值成功 "); } } },null); //删除节点 zookeeper.delete("/m1",-1); //检测节点是否存在 Stat existStat = zookeeper.exists("/m1",watcher); if(null== existStat){ System.out.println("节点不存在"); } //权限控制 ZooKeeper zk = new ZooKeeper(connectStr,sessionTimeout,watcher); zk.addAuthInfo("digest","pass".getBytes("utf8")); String m6 = zk.create("/m6","mv6".getBytes("utf-8"), ZooDefs.Ids.CREATOR_ALL_ACL,CreateMode.PERSISTENT); //创建有权限的节点 byte[] byteResult = zk.getData("/m6",watcher,stat); //有权限读取 String result = new String(byteResult,"utf-8"); System.out.println("result with auth:"+result); try{ byteResult = zookeeper.getData("/m6",watcher,stat); //无权限读取 result = new String(byteResult,"utf-8"); System.out.println("result without auth:"+result); }catch (Exception e){ e.printStackTrace(); } TimeUnit.HOURS.sleep(1); } static class SimpleWatcher implements Watcher{ //事件监听器,客户端注册后,当事件发生时,会通知客户端 public void process(WatchedEvent event) { System.out.println("event is :"+event); } } }输出:
zookeeper state: CONNECTING
event is :WatchedEvent state:SyncConnected type:None path:null
zookeeper state : CONNECTED
zookeeper state : CONNECTING
event is :WatchedEvent state:SyncConnected type:None path:null
同步获取子节点:[ m6]
异步获取子节点:[ m6]
同步获取节点的值 m1 :mv1
异步获取节点的值 m1 :mv1
event is :WatchedEvent state:SyncConnected type:NodeDataChanged path:/m1
异步更新值成功
event is :WatchedEvent state:SyncConnected type:NodeChildrenChanged path:/
节点不存在
event is :WatchedEvent state:SyncConnected type:None path:null
result with auth:mv6
四、基于开源zookeeper的java客户端ZkClient使用
ZkClient是对Zoookeeper客户端的包装,包装自动序列化和反序列化、通过Listener进行监听等。
1、添加maven依赖
<dependency> <groupId>org.apache.zookeeper</groupId> <artifactId>zookeeper</artifactId> <version>3.4.6</version> </dependency> <dependency> <groupId>com.github.sgroschupf</groupId> <artifactId>zkclient</artifactId> <version>0.1</version> </dependency>
2、代码实例
public class ZkClientMain { public static void main(String[] args) throws Exception { ZkClient zkClient = new ZkClient("127.0.0.1:2181",5000); //创建会话 zkClient.subscribeChildChanges("/", new IZkChildListener() { //监听子节点变化 public void handleChildChange(String s, List<String> list) throws Exception { System.out.println("parent path: "+ s+ " now children is:"+list); } }); zkClient.create("/c1","cd1", CreateMode.PERSISTENT); //创建节点 List<String> children = zkClient.getChildren("/");//读取子节点 System.out.println("children : "+children); String cv = zkClient.readData("/c1"); //读取节点数据 System.out.println("value of c1 :"+cv); zkClient.subscribeDataChanges("/c1", new IZkDataListener() { //监听节点变化 public void handleDataChange(String s, Object o) throws Exception { System.out.println(s+" data change :"+o); } public void handleDataDeleted(String s) throws Exception { System.out.println(s+" data delete"); } }); zkClient.writeData("/c1","nncv1"); //更新节点数据 System.out.println("value of c1 :"+zkClient.readData("/c1")); zkClient.delete("/c1"); //删除节点数据 boolean existFlag = zkClient.exists("/c1"); //判断节点是否存在 if(!existFlag){ System.out.println("/c1 节点不存在"); } TimeUnit.HOURS.sleep(1); } }输出:
children : [c1]
parent path: / now children is:[c1]
value of c1 :cd1
value of c1 :nncv1
/c1 data change :nncv1
/c1 节点不存在
/c1 data delete
parent path: / now children is:[]