Zookeeper学习
常用命令
- 客户端简单的命令:
临时节点当会话结束的时候,节点就会消失了
curator
curator是zookeeper的java客户端库
创建连接
// 工厂创建,fluent风格
CuratorFramework client = CuratorFrameworkFactory.builder()
// ip端口号 下边是集群的写法
.connectString("192.168.133.133:2181,192.168.133.133:2182,192.168.133.133:2183")
// 会话超时
.sessionTimeoutMs(5000)
// 重试机制,这里是超时后1000毫秒重试一次
.retryPolicy(new RetryOneTime(1000))
// 名称空间,在操作节点的时候,会以这个为父节点
.namespace("create")
.build();
// 开启连接
client.start();
创建节点
普通创建,不带数据(如果没有指定数据,默认会把客户端的ip地址作为数据):
client.create().forPath("/node1");
创建带数据的节点,数据的格式必须是字节数据:
client.create().forPath("/node1", "hhhh".getBytes());
创建设置节点类型的节点,具体类型可以使用CreateMode的枚举类型:
client.create()
// 节点的类型,这里使用的是临时节点
.withMode(CreateMode.EPHEMERAL)
// arg1:节点路径,arg2:节点数据
.forPath("/node1",new byte[0]);
创建多级节点,zookeeper不能在父节点不存在的情况下,直接创建子节点,例如/app1不存在,直接创建/app1/node,但是api提供了额外的方法:
client.create()
// 递归创建
.creatingParentsIfNeeded()
.forPath("/app1/node",new byte[0]);
查询节点
查询节点数据
// 获取数据,相当于get
byte[] bytes = client.getData()
.forPath("/node");
System.out.println(new String((bytes)));
查询子节点,相当于ls,注意的path是基于命名空间的
List<String> list = client.getChildren().forPath("/app1");
查询节点信息,相当于ls -s
Stat status = new Stat();
// 获取数据
byte[] bytes = client.getData()
// 存贮状态信息到status
.storingStatIn(status)
.forPath("/node");;
修改节点
普通修改(不推荐)
client.setData().forPath("/app1", "cha".getBytes());
根据版本号修改节点数据(推荐),为了避免与其他客户端冲突
// 根据版本号修改数据,先查询version
Stat status = new Stat();
client.getData().storingStatIn(status).forPath("/app1");
int version = status.getVersion();
client.setData().withVersion(version).forPath("/app1", "kk".getBytes());
删除节点
删除单个节点
client.delete().forPath("/app1");
删除带有子节点的节点(递归删除)
client.delete().deletingChildrenIfNeeded().forPath("/app1");
必须成功的删除,为了防止会话超时、网络抖动等问题,本质就是重试
client.delete().guaranteed().forPath("/app1");
回调,删除之后增加一些操作:
client.delete().guaranteed().inBackground(new BackgroundCallback() {
@Override
public void processResult(CuratorFramework curatorFramework, CuratorEvent curatorEvent) throws Exception {
// do some thing 删除之后的操作
}
}).forPath("/app1");
分布式锁
-
为什么是临时节点?
为了防止客户端宕机的时候,无法释放锁 -
为什么是顺序节点?
为了找最小节点,使得最小节点获取锁
watch机制
watch是一次性的,一旦出发后,服务端的WatchManager就会删除这个事件,所以后续还想继续监听的话,客户端需要重新注册监听