Curator基本操作(Zookeeper节点增删改查)
Curator是Zookeeper的Java客户端库,官网为 https://curator.apache.org
。
环境
- Ubuntu 22.04
- Zookeeper 3.7.1
- JDK 17.0.3.1
- IntelliJ IDEA 2022.1.3
- Curator 5.4.0
准备
创建Maven项目 test1215
。
打开 pom.xml
文件,添加如下依赖:
<!-- https://mvnrepository.com/artifact/org.apache.curator/curator-recipes --><dependency><groupId>org.apache.curator</groupId><artifactId>curator-recipes</artifactId><version>5.4.0</version></dependency><!-- https://mvnrepository.com/artifact/org.apache.curator/curator-framework --><dependency><groupId>org.apache.curator</groupId><artifactId>curator-framework</artifactId><version>5.4.0</version></dependency><!-- https://mvnrepository.com/artifact/junit/junit --><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.13.2</version><scope>test</scope></dependency>
在 src/test/java
目录下,创建测试文件 Test1215.java
。
首先加上连接和关闭连接的测试:
package pkg1;import org.apache.curator.RetryPolicy;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;public class Test1215 {private CuratorFramework client;@Beforepublic void testConnect() {RetryPolicy retryPolicy = new ExponentialBackoffRetry(3000, 10);client = CuratorFrameworkFactory.builder().connectString("localhost:2181").sessionTimeoutMs(60 * 1000).connectionTimeoutMs(15 * 1000).retryPolicy(retryPolicy).namespace("test1215").build();client.start();}// quit@Afterpublic void testClose() {if (client != null) {client.close();}}
注:
- 本例是单机Zookeeper,所以connectionString是
localhost:2181
,如果是Zookeeper集群,则connectionString是localhost:2181,localhost:2182,localhost:2183
这样的。 - 在创建连接时,指定了namespace为
test1215
,表示所有的操作都是在/test1215
节点下操作的,否则默认是在根节点/
下操作的。
增删改查操作
创建节点
// create <node>@Testpublic void test1() throws Exception {client.create().forPath("/app1");}
运行测试,然后在命令行下查看:
ls /
[test1, test1215, test20000000003, test20000000004, test30000000005, zookeeper]
ls /test1215
[app1]
可见,创建了节点 /test1215
和 /test1215/app1
。
get /test1215/app1
127.0.1.1
注意,如果不设置数据,默认会设置为机器的IP地址,即 127.0.0.1
。
若要显式设置数据,则 forPath()
方法需要多一个参数。
// create <node> <data>@Testpublic void test2() throws Exception {client.create().forPath("/app2", "Hello".getBytes());}
若要设置节点的临时性和顺序性,则要用 withMode()
方法:
// create -es <node>@Testpublic void test3() throws Exception {client.create().withMode(CreateMode.EPHEMERAL_SEQUENTIAL).forPath("/app3");}
本例中创建了一个临时且顺序的节点。
注意,会话结束后,临时节点就会自动删除,所以要验证的话,需要设置断点,让程序暂停,然后在命令行下查看:
ls /test1215
[app1, app2, app30000000002]
可见,创建了顺序节点 app30000000002
。
等运行结束后再查看:
ls /test1215
[app1, app2]
可见,临时节点在会话结束之后自动删除了。
如果需要一次性创建多级节点,则要用 creatingParentsIfNeeded()
方法:
// create <parent>// create <parent/child>@Testpublic void test4() throws Exception {client.create().creatingParentsIfNeeded().forPath("/app4/child1");client.create().creatingParentsIfNeeded().forPath("/app4/child2/aaa");}
注:貌似没有对应的命令,Curator可能是一级一级创建的。
运行测试,然后在命令行下查看:
ls /test1215
[app1, app2, app4]
ls /test1215/app4
[child1, child2]
ls /test1215/app4/child2
[aaa]
注意:默认的数据 127.0.0.1
是设置在最小的节点上的,本例中为 /test1215/app4/child1
和 /test1215/app4/child2/aaa
。
查询节点
获取节点数据:
// get <node>@Testpublic void test5() throws Exception {byte[] data = client.getData().forPath("/app2");String str = new String(data);System.out.println(str);}
运行结果如下:
Hello
查询子节点:
// ls <node>@Testpublic void test6() throws Exception {List<String> list = client.getChildren().forPath("/");list.forEach(System.out::println);}
运行结果如下:
app2
app1
app4
注意:这里的 /
实际上是 /test1215
,因为设置了namespace。
查询节点状态:
// ls -s <node>@Testpublic void test7() throws Exception {Stat stat = new Stat();System.out.println(stat);client.getData().storingStatIn(stat).forPath("/app2");System.out.println(stat);}
运行结果如下:
0,0,0,0,0,0,0,0,0,0,0103,103,1671156504367,1671156504367,0,0,0,0,5,0,103
设置节点数据
直接更新节点数据:
// set <node> <data>@Testpublic void test8() throws Exception {client.setData().forPath("/app2", "China".getBytes());}
运行测试,然后在命令行下查看:
get /test1215/app2
China
根据版本号更新数据:
// set -v <version> <node> <data>@Testpublic void test9() throws Exception {Stat stat = new Stat();client.getData().storingStatIn(stat).forPath("/app2");int version = stat.getVersion();System.out.println("Version = " + version);client.setData().withVersion(version).forPath("/app2", "good".getBytes());
// client.setData().withVersion(100).forPath("/app2", "good".getBytes());}
运行结果如下:
Version = 1
注意:本例中,先获取节点的版本,在更新数据时,带上该版本号,以确保没有并发问题。如果此时实际的版本号已改变,二者不相等,则不会更新数据,而是抛出异常。
更新成功后版本号会加1。本例中,原先的版本号为1,如果更新成功,则版本号会变成2。
在命令行验证版本号:
ls -s /test1215/app2
[]
cZxid = 0x67
ctime = Fri Dec 16 10:08:24 CST 2022
mZxid = 0x80
mtime = Fri Dec 16 10:25:16 CST 2022
pZxid = 0x67
cversion = 0
dataVersion = 2
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 4
numChildren = 0
可见,当前的 dataVersion
已经变为2。
如果更新时,获取的版本号和实际版本号不相等(本例中可用硬编码来指定一个错误的版本号),则会报错:
org.apache.zookeeper.KeeperException$BadVersionException: KeeperErrorCode = BadVersion for /test1215/app2
删除节点
删除没有子节点的节点:
// delete <node>@Testpublic void test10() throws Exception {client.delete().forPath("/app1");}
运行测试,然后在命令行下查看:
ls /test1215
[app2, app4]
可见 /test1215/app1
已经删除了。
删除带有子节点的节点:
// deleteall <node>@Testpublic void test11() throws Exception {client.delete().deletingChildrenIfNeeded().forPath("/app4/child2");}
运行测试,然后在命令行下查看:
ls /test1215/app4
[child1]
可见, /test1215/app4/child2
连同其子节点 /test1215/app4/child2/aaa
一起删除了。
确保删除成功:
// delete <node>@Testpublic void test12() throws Exception {client.delete().guaranteed().forPath("/app4/child1");}
运行测试,然后在命令行下查看:
ls /test1215/app4
[]
本例中看不出 guaranteed()
的效果。
可以在删除节点时,添加一个回调函数:
// delete <node>@Testpublic void test13() throws Exception {client.delete().inBackground(new BackgroundCallback() {@Overridepublic void processResult(CuratorFramework curatorFramework, CuratorEvent curatorEvent) throws Exception {System.out.println("Deleted");System.out.println(curatorEvent);}}).forPath("/app2");}
运行结果如下:
Deleted
CuratorEventImpl{type=DELETE, resultCode=0, path='/app2', name='null', children=null, context=null, stat=null, data=null, watchedEvent=null, aclList=null, opResults=null}
在命令行下查看:
[zk: localhost:2181(CONNECTED) 107] ls /test1215
[app4]
可见 /test1215/app2
已经删除了。
注意,此时如果把 /test1215/app4
删除,则 /test1215
节点为空,大概几秒钟后也就自动删除了。但是刚才把 /test1215/app4
下的所有子节点都删除之后, /test1215/app4
节点为空,并不会自动删除。可见用namespace创建的节点有一个特性:当其为空时,就会自动删除。这应该也是封装的Zookeeper的特性吧,有待研究。
Curator基本操作(Zookeeper节点增删改查)相关推荐
- 自定义 RPC框架3——JAVA实现Zookeeper节点增删改查
Zookeeper安装 zookeeper的安装在之前的文章中已经写过:https://blog.csdn.net/qq_45587153/article/details/123630361?spm= ...
- ZooKeeper【基础 02】zookeeper-3.6.0 常用Shell命令(节点增删改查+监听器+四字指令)
我使用的安装文件是 apache-zookeeper-3.6.0-bin.tar.gz ,以下内容均以此版本进行说明.这个是官网的3.6.0<CLI命令说明> 感兴趣的可以查看. 1.1 ...
- ZooKeeper【基础知识 02】zookeeper-3.6.0 常用Shell命令(节点增删改查+监听器+四字指令)
我使用的安装文件是 apache-zookeeper-3.6.0-bin.tar.gz ,以下内容均以此版本进行说明.这个是官网的3.6.0<CLI命令说明> 感兴趣的可以查看. 1.1 ...
- JS DOM节点增删改查 属性设置
一.节点操作 增 createElement(name)创建元素 appendChild();将元素添加 删 获得要删除的元素 获得它的父元素 使用removeChild()方法删除 改 第一种方式: ...
- Zookeeper JavaApi 增删改查
官网API http://zookeeper.apache.org/doc/r3.4.6/api/index.html JAR包 \zookeeper-3.3.6\lib\ jline-0.9.94. ...
- Zookeeper后端开发工具Curator的使用 | Curator对节点的增删改查 | ACL权限控制 | 分布式锁 | 分布式计数器 | 附带最新版本下载
前言 Curator是Apache开源的一个Java工具类,通过它操作Zookeeper会变得极度舒适! 前置条件:已掌握的基本操作,比如在后台可以增减节点.ACL权限设置等. 1.Zookeeper ...
- zookeeper curator客户端之增删改查
zookeeper curator客户端之增删改查 zookeeper安装:https://www.cnblogs.com/zwcry/p/10272506.html curator客户端是Apach ...
- Zookeeper 客户端API调用示例(基本使用,增删改查znode数据,监听znode,其它案例,其它网络参考资料)
9.1 基本使用 org.apache.zookeeper.Zookeeper是客户端入口主类,负责建立与server的会话 它提供以下几类主要方法 : 功能 描述 create 在本地目录树中创建 ...
- zkcli远程连接_ZooKeeper客户端 zkCli.sh 节点的增删改查
zkCli.sh 在 bin 目录下的 zkCli.sh 就是ZooKeeper客户端 ./zkCli.sh -timeout 5000 -server 127.0.0.1:2181 客户端与 ...
最新文章
- 功能性平台创新-农业大健康·杨建国:谋定都江堰精华灌区
- java调用本地shell_java通过ProcessBuilder执行本地shell命令 获取ip配置信息
- Excel快速改变行列的次序
- 2017蓝桥杯省赛---java---C---2(兴趣小组)
- activiti5.22 springboot 流程引擎 实战全过程
- 遵义大数据中心项目工程概况_市委书记张新文到曹州云都大数据中心等项目现场调研建设情况...
- Django中示例验证码的实现总结
- 在php中使用CKEDITOR在线编辑器
- python 二分查找_LeetCode基础算法题第120篇:二分查找算法
- 事务的acid属性是指_Mysql事务的性质 为什么要用事务?
- x射线计算机断层成像_医疗保健中的深度学习-X射线成像(第4部分-类不平衡问题)...
- 加载八叉树索引文件_mysql innodb索引原理
- 【备忘】年薪50万2017年最新北风网Spark2.0从入门到精通教程
- 记一次有惊无险的 JVM 优化经历
- qiankun 出现[import-html-entry]: error occurs while executing normal script
- BZOJ4567[Scoi2016]背单词
- 图像处理——人脸情绪识别(python卷积神经网络)
- Twitter新任80后印度裔CEO,为啥是他?
- Windows10文件后缀名不显示·解决方法
- Vue 利用后端的数据字典和Map对象实现表格列字段动态转义的处理方案
热门文章
- 把Form转换成TXT格式的文件
- convs在MATLAB中,matlab2_MATELAB课程设计_ppt_大学课件预览_高等教育资讯网
- 从val_loss,train_loss,test_loss中产生的问题
- STM32液晶显示中英文
- dhcp二层中继和三层中继
- 对苹果maccms网站漏洞进行修复解决过程
- 机车安装鸿蒙系统,华为鸿蒙系统2.0版本来了:9月11日发布 打通PC、手表、车机等...
- html表格突出显示,java-如何突出显示jtable单元格的文本?
- java斗地主发牌_实现斗地主发牌(java)
- 计算机系统仿真缩写,仿真语言