ZooKeeper学习笔记五 ZooKeeper开源客户端ZkClient

本文学习资源来自《从Paxos到ZooKeeper分布式一致性原理与实践》

ZkClient

ZkClient 在ZooKeeper原生API接口之上进行了封装,是一个更易用的ZooKeeper客户端。同时,ZkClient在内部实现了诸如Session超时重连、Watcher反复注册等功能,使得ZooKeeper客户端的这些繁琐的细节工作对开发人员透明。

连接

package zookeeper;

import java.io.IOException;

import org.I0Itec.zkclient.ZkClient;

public class Create_Session_Sample {
    public static void main(String[] args)throws IOException,InterruptedException{
        ZkClient zkClient = new ZkClient("127.0.0.1:2181",5000);
        System.out.println("ZooKeeper session established");
    }
}

创建节点

ZkClient 中提供了以下一系列接口来创建节点,开发者可以通过这些接口来进行各种类型的节点创建:

String create(final String path,Object data,final CreateMode mode)
String create(final String path,Object dta,final List<ACL> acl,final CreateMode mode)
void create(final String path,Object data,final CreateMode mode,final AsyncCallback.StringCallback callback,final Object context)
void createEphemeral(final String path)
void createEphemeral(final String path,final Object data)
void createPersistent(String path);
void createPersistent(String path,boolean createParents);
void createPersistent(String path,Object data);
void createPersistent(String path,List<ACL> acl,Object data);
String createPersistentSequential(String path,Object data);
String createEphemeralSequential(final String path,final Object data);

ZkClient提供的接口,由于支持了自定义序列化器,因此可以传入复杂对象作为参数。
boolean createParents参数支持递归创建节点。

删除节点

在ZkClient中,可以通过以下API来删除指定节点:

boolean delete(final String path)
delete(final String path,final AsyncCallback.VoidCallback callback,final Object context);
boolean deleteRecursive(String path);

deleteRecursive支持自动逐层遍历删除节点。

读取结点

在ZkClient中,可以通过以下API来获取指定节点的子节点列表:

List<String> getChildren(String path)

ZkClient提供的API没有了Watcher注册的功能。ZkClient引入了Listener的概念,客户端可以通过注册相关的事件监听来实现对ZooKeeper服务端事件的订阅。在获取子节点列表这个接口上,可以通过如下API来进行注册监听:

List<String>subscribeChildChanges(String path,IZkChildListener listener)

通过该API的调用,就完成了事件监听的注册。该监听 是对子节点列表变更的监听,也就是说,一旦子节点列表发生变更,ZooKeeper服务端就会向客户端发出事件通知,由这个Listener来处理。

public interface IZkChildListener{
   public void handleChildChange(String parentPath,List<String> currentChilds) throws Exception;
}

代码示例:

package zookeeper;

import java.util.List;

import org.I0Itec.zkclient.IZkChildListener;
import org.I0Itec.zkclient.ZkClient;

public class Get_Children_Sample {
    public static void main(String[] args)throws Exception{
        String path = "/zk-book";
        ZkClient zkClient = new ZkClient("127.0.0.1:2181",5000);
        zkClient.subscribeChildChanges(path,new IZkChildListener(){

            @Override
            public void handleChildChange(String parentPath, List<String> currentChilds)
                    throws Exception {
                System.out.println(parentPath + " 's child changed,currentChilds:" + currentChilds);

            }

        });
        zkClient.createPersistent(path);
        Thread.sleep(1000);
        System.out.println(zkClient.getChildren(path));
        Thread.sleep(1000);
        zkClient.createPersistent(path + "/c1");
        Thread.sleep(1000);
        zkClient.delete(path + "/c1");
        Thread.sleep(1000);
        zkClient.delete(path);
        Thread.sleep(Integer.MAX_VALUE);
    }
}

运行结果:

/zk-book 's child changed,currentChilds:[]
[]
/zk-book 's child changed,currentChilds:[c1]
/zk-book 's child changed,currentChilds:[]
/zk-book 's child changed,currentChilds:null
  • 客户端可以对一个不存在的节点进行监听
  • 一旦客户端对一个节点注册了子节点列表变更监听之后,那么当该节点的子节点列表发生变更的时候,服务端都会通知客户端,并将最新的子节点列表发送给客户端。
  • 该节点本身的创建或删除也会通知到客户端。

另外与ZooKeeper原生的Watcher不同的是,ZkClient的Listener不是一次性的,客户端只需要注册一次就会一直生效。

读取数据

<T extends Object> T readData(String path)
<T extends Object> T readData(String path,boolean returnNullIfPathNotExists)
<T extends Object> T readData(String path,Stat stat)

该接口对服务端事件的监听,同样是通过注册指定的Listener来实现的。

public interface IZkDataListener{
   public void handleDataChange(String dataPath,Object data) throws Exception;
   public void handleDataDeleted(String dataPath) throws Exception;
}

示例代码:

package zookeeper;

import org.I0Itec.zkclient.IZkDataListener;
import org.I0Itec.zkclient.ZkClient;

public class Get_Data_Sample {
    public static void main(String[] args) throws Exception{
        String path = "/zk-book";
        ZkClient zkClient = new ZkClient("127.0.0.1:2181",5000);
        zkClient.createEphemeral(path,"123");
        zkClient.subscribeDataChanges(path,new IZkDataListener(){

            @Override
            public void handleDataChange(String dataPath, Object data) throws Exception {
                System.out.println("Node " + dataPath + " changed,new data:." + data);
            }

            @Override
            public void handleDataDeleted(String dataPath) throws Exception {

                System.out.println("Node" + dataPath + " deleted");

            }

        });
        System.out.println(zkClient.readData(path));
        zkClient.writeData(path, "456");
        Thread.sleep(1000);
        zkClient.delete(path);
        Thread.sleep(Integer.MAX_VALUE);
    }
}

运行结果:

123
Node /zk-book changed,new data:.456
Node/zk-book deleted

更新数据

void writeData(String path,Object data);
void writeData(final String path,Object data,final int expectedVersion)

检测数据是否存在

boolean exists(final String path)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

编程圈子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值