zookeeper客户端(一)原生Zookeeper API的使用
目录
1、zookeeper自带的zkCli客户端命令行
2、使用zookeeper原生API
1、zookeeper自带的zkCli客户端命令行
当进入zkCli的命令行,可以输入help显示出所有操作的命令,如下表:
命令基本语法 | 功能描述 |
help | 显示所有操作命令 |
ls path [watch] | 使用 ls 命令来查看当前znode中所包含的内容 |
ls2 path [watch] | 查看当前节点数据并能看到更新次数等数据 |
create | 普通创建 -s 含有序列 -e 临时(重启或者超时消失) |
get path [watch] | 获得节点的值 |
set | 设置节点的具体值 |
stat | 查看节点状态 |
delete | 删除节点 |
rmr | 递归删除节点 |
示例:
查看所有节点: ls / ls2 / (显示的更详细)
创建普通节点: create path data
如:create /xiyou "sunwukong"
获取节点值:get path
如:get /xiyou
创建临时节点:create -e /sanguo "xiaoqiao"
创建的这个临时节点,在客户端退出时就会被删除
创建带序号节点:create -s /xiyou/sunhouzi "sunwukong"
修改节点的值: set path data
如:set /xiyou "wujing"
节点的值变化监听:get /xiyou watch(说明:这种监听只会生效一次)
验证:可以在A客户端中执行监听,在B客户端修改/xiyou的值,此时A客户端会出现如下提示
WatchedEvent state:SyncConnected type:NodeDataChanged path:/sanguo/simayi
说明监听节点的值已被修改。
节点路径的变化监听:ls /sanguo watch(说明:这种监听只会生效一次)
验证:在A客户端执行监听,通过B客户端在/sanguo目录下新增一个节点,在hadoop102上观察效果
在A客户端会出现如下提示:
WatchedEvent state:SyncConnected type:NodeChildrenChanged path:/sanguo
删除节点(子节点):delete /xiyou/bajie
递归删除节点: rmr /xiyou
查看节点状态: stat /sanguo
2、使用zookeeper原生API
(1)环境搭建
使用maven工程,在pom.xml中引入原生的Zookeeper API。
<!--zookeeper原生API -->
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.4.10</version>
</dependency>
<!-- 单元测试-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
version>4.12</version>
<scope>compile</scope>
/dependency>
(2)代码示例
a、创建客户端
new Zookeeper(zookeeper地址, session超时时间, 监听事件)
原生的zookeeper存在缺陷:注册事件只生效一次,因此需要人为在process回调中再次注册监听事件。
@Before
public void initZk() throws Exception {
zooKeeper = new ZooKeeper(connectString, sessionTimeout, new Watcher() {
public void process(WatchedEvent watchedEvent) {
//监听发生后触发的事件
System.out.println(watchedEvent.getType() + "---" + watchedEvent.getPath());
//再次注册事件进行监听
try {
zooKeeper.exists("/liuzhoujian", true);
zooKeeper.getChildren("/", true);
} catch (KeeperException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
}
b、创建节点
@Test
public void createNode() throws Exception {
//第一个参数:节点路径
//第二个参数:存储的数据
//第三个参数:访问的权限
//第四个参数:节点的类型
String node = zooKeeper.create("/liuzhoujian", "movie.txt".getBytes(),
ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
System.out.println(node);
}
c、删除节点
当不需要某个节点,或者某个节点的信息已经失效时,使用delete方法可以删除节点,删除时需要指定节点的版本号,如果设置为-1,则匹配所有版本,zookeeper会比较删除的节点版本是否和服务器上的版本一致,如果不一致则抛出异常。
zookeeper.delete("/liuzhoujian", -1);
d、设置和获取节点内容
setData设置数据,getData获取数据,其中每个节点最多存入1M数据。
getData() 第一个参数:节点路径 第二个参数:是否使用监听,false表示不使用 第三个参数:stat 表示节点的状态,将会返回该节点当前的状态信息
//设置版本号为-1,如果匹配不到相应节点会抛出异常
zooKeeper.setData("/liuzhoujian", "hello".getBytes(), -1);
Stat stat = new Stat();
byte[] data = zooKeeper.getData("/liuzhoujian", false, stat);
e、添加子节点
String parent= zooKeeper.create("/liuzhoujian", "parent".getBytes(),
ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
String child = zooKeeper.create("/liuzhoujian/child", "child".getBytes(),
ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
f、判断节点是否存在
@Test
public void isExist() throws Exception {
Stat stat = zooKeeper.exists("/liuzhoujian", true); //watch为true表示开启监听,默认只监听一次,需在process回调中再次配置
System.out.println(stat == null ? "nost exist" : "exist");
Thread.sleep(Long.MAX_VALUE); //为了阻塞,能观察到监听器的处理效果
};
g、获取根目录下所有节点
@Test
public void getNode() throws Exception {
List<String> children = zooKeeper.getChildren("/", true);
for(String node : children) {
System.out.println(node);
}
Thread.sleep(Long.MAX_VALUE);
}
g、watcher的实现
当节点状态发生变化时,通过watcher绘制,可以让客户端得到通知,watcher需要实现org.apache.ZooKeeper.Watcher接口。节点的状态变化主要分为:
节点状态变化 | 解释 |
EventType.NodeDeleted | 删除节点 |
EventType.NodeChildrenChanged | 修改节点的子节点 |
EventType.NodeCreated | 创建节点 |
EventType.NodeDataChanged | 修改节点数据 |
public class ZKWatcher implementes Watcher {
@Override
public void process(WatchedEvent event) {
//监听发生后触发的事件
if(event.getType() == Event.EventType.NodeDeleted) {
System.out.println("node deleted");
} else if(event.getType() == Event.EventType.NodeChildrenChanged) {
System.out.println("nodeChildrenChanged");
} else if(event.getType() == Event.EventType.NodeCreated) {
System.out.println("node created");
} else if(event.getType() == Event.EventType.NodeDataChanged) {
System.out.println("node data changed");
}
}
}
需要注意的是:Zookeeper的watcher是一次性的,每次在处理完状态变化事件后,需要重新注册watcher。这个特性也使得在处理时间和重新加上watcher这段时间发生的节点状态变化无法被感知。
文章参考:《大型分布式网站架构设计与实践》
还没有评论,来说两句吧...