zookeeper-3. java操作z

发布时间:2019-09-15 09:54:05编辑:auto阅读(1377)


    对于Zookeeper的建立连接、增删改查、以及监视节点的变化操作。


    一、简单实例操作zookeeper原生API


    1. 创建会话方法:客户端可以通过创建一个zookeeper实例来连接zookeeper服务器。

    参数说明:

    connectString:连接服务器列表,用“,”分割;

    sessionTimeout:心跳检测时间周期(毫秒);

    watcher:事件处理通知器;

    canBeReadOnly:标识当前会话是否支持只读;

    sessionId, sessionPasswd:提供链接zookeeper的sessionId和密码,通过这俩确定唯一一台客户端,目的是可以提供重复会话;

    注意:zookeeper客户端和服务器端会话的建立是一个异步的过程


    /** zookeeper地址 */
    static final String CONNECT_ADDR = "192.168.80.88:2181,192.168.80.87:2181,192.168.80.86:2181";
    
    /** session超时时间 */
    static final int SESSION_OUTTIME = 2000;//ms
    
    /** 阻塞程序执行,用于等待zookeeper连接成功,发送成功 */
    static final CountDownLatch connectedSemaphore = new CountDownLatch(1);
    
    //创建zookeeper连接
    ZooKeeper zk = new ZooKeeper(CONNECT_ADDR, SESSION_OUTTIME, new Watcher(){
        @Override
        public void process(WatchedEvent event) {
          //连接状态
           KeeperState keeperState = event.getState();
           
          //事件类型
           EventType eventType = event.getType();
           
           //如果是建立连接
            if(KeeperState.SyncConnected == keeperState){
            
                if(EventType.None == eventType){
                
                //如果建立连接成功,则发送信号量,让后续阻塞程序向下执行
                connectedSemaphore.countDown();
                System.out.println("zk 建立连接");
                
                }
           }
        }
    });
    //进行阻塞
    connectedSemaphore.await();



    2. 创建节点(znode)方法:create  提供同步和异步两种方式

    同步方式

    参数说明:

    path:节点路径(名称),不允许递归创建节点;

    data:节点内容,是字节数组,不支持序列化方式,如果需要序列化,可使用java相关的序列化框架如Hessian、Kryo框架;

    acl: 节点权限,使用Ids.OPEN_ACL_UNSAFE开放权限即可;

    createMode:节点类型,提供了以下四种

    PERSISTENT(持久节点)

    PERSISTENT_SEQUENTIAL(持久顺序节点)

    EPHEMERAL(临时节点)

    EPHEMERAL_SEQUENTIAL(临时顺序节点)

    //创建父节点,不允许递归创建节点,不支持序列化方式

    zk.
    create
    ("/testRoot", "testRoot".getBytes(), 
    Ids.OPEN_ACL_UNSAFE
    , 
    CreateMode.PERSISTENT
    );


    异步方式:(再同步的基础上添加两个参数)

    参数说明:

    StringCallback:注册一个异步回调函数,要实现AsynCallBack.StringCallBack接口,重写proce***esult()方法,当节点创建完毕后执行此方法;

    ·rc:服务器响应码 0表示成功-4表示连接 -110表示制定节点存在 -112表示会话已过期

    ·path:接口调用时传入API的数据节点的路径参数

    ·ctx:为调用接口传入API的ctx,

    ·name:实际在服务器端创建节点的名称

    Object:传递给回调函数的参数,一般为上下文信息;


    //异步创建节点

    zooKeeper.create("/apis/","create api1".getBytes(),
    
        Ids.OPEN_ACL_UNSAFE,CreateMode.EPHEMERAL_SEQUENTIAL,
        
        new StringCallback(){
        
            public void proce***esult(int rc, String path,Object ctx, String name) {
            if(rc==0){
            
                System.out.println("创建节点完成");
                countDownLatch.countDown();
            }
        }
     },"12345");



    3. 判断节点(znode)是否存在:exists

    参数说明:

    path:路径

    watcher:注册的watcher对象,一旦之后节点内容有变更,则会向客户端发送通知,该参数可以为null。(用于三类事件监听:节点的创建、删除、更新)

    watch:是否使用watcher,如果为true则默认使用上文中的watcher。false则不使用watcher。

    cb:回调函数

    ctx:用于传递的上下文信息对象

    注意:exists方法的意义在于无论节点是否存在,都可以进行注册watcher,能够对节点的创建、删除、修改进行监听,但是其子节点变化,不会通知客户端。


    //判断节点是否存在
    zk.exists("/testRoot/children", false)



    4. 获得节点(znode)数据:getData

    参数说明:

    path:路径

    watcher:注册的watcher对象,一旦之后节点内容有变更,则会向客户端发送通知,该参数可以为null。(用于三类事件监听:节点的创建、删除、更新)

    watch:是否使用watcher,如果为true则默认使用上文中的watcher。false则不使用watcher。


    //获取节点信息
    byte[] data = zk.getData("/testRoot", false, null);
    
    System.out.println(new String(data));



    5. 修改节点(znode)数据:setData

    参数说明:

    path:路径

    data:节点内容,是字节数组,不支持序列化方式,如果需要序列化,可使用java相关的序列化框架如Hessian、Kryo框架;

    version:版本号,-1则跳过版本检查;


    //修改节点的值
    zk.setData("/testRoot", "modify data root".getBytes(), -1);


    6. 遍历子节点:getChildren

    参数说明:

    path:路径

    watcher:注册的watcher对象,一旦在本次节点获取后,子节点列表发生变更的话,那么会向客户端发出通知。

    watch:是否需要注册一个watcher,如果为true则默认zookeeper客户端上文中的watcher。false则不使用watcher。

    stat:指定数据节点的节点状态信息。


    注意:当子节点被添加或删除时,服务器就会触发一个NodeChildrenChanged类型的事件通知,该通知中不包含最新的节点列表。客户端必须主动重新获取。watcher是一次性的,即触发后失效,因此客户端需要反复注册。


    //遍历节点下的所有数据
    List<String> nodeChildName=zookeeper.getChildren("/testRoot", false);
    
    for(String path:nodeChildName){
    
        //获得节点的数据
        byte[] data=zookeeper.getData(("/testRoot/"+path), false, null);
        
        //修改节点的数据
        zookeeper.setData("/testRoot/"+path, (path+"newData").getBytes() , -1);
        
    }

     


    7. 删除节点(znode)数据:delete

    参数说明:

    path:路径

    version:版本号,-1则跳过版本检查;


    //删除节点,只能删除叶子节点
    zk.delete("/testRoot/children", -1);
    
    //关闭连接
    zk.close();


    注意:在zookeeper中,不允许级联删除。必须先删除子节点,再删除其父节点。



    二、Watcher

    zookeeper有watch事件,是一次性触发的,当watch监视的数据发生变化时,通知设置了该watch的client,即watcher。watcher是监听数据发送了某些变化,有对应的事件类型和状态类型。

    ·事件类型EventType:(zonde节点相关的)

    ·状态类型KeeperState:(与客户端实例相关的)


    watcher的特性:一次性、客户端串行执行、轻量。

    一次性:zookeeper有watch事件,是一次性触发的,当watch监视的数据发生变化时,通知设置了该watch的client,即watcher,由于zookeeper的监控都是一次性的所以每次必须设置监控。

    客户端串行执行:客户端watcher回调的过程是一个串行同步的过程。

    轻量:WatchedEvent是zookeeper整个Watcher通知机制的最小通知单元,包括三部分:通知状态事件类型节点路径。也就是说Watcher通知只会告诉客户端发生了事件而不会告诉其具体内容,需要客户自己进行获取。


    public class WatchedEvent {
        final private KeeperState keeperState;
        
        final private EventType eventType;
        
        private String path;
    }


    设置监听的方法有以下方法


    1)监听节点的创建、修改、删除,对应的事件为:NodeDataChanged\NodeCreated\NodeDeleted


    zookeeper.exists(path, true);

    zookeeper.getData(path, true, null);


    2)监听子节点创建和删除,对应的事件:NodeChildrenChanged


    zookeeper.getChildren(path, true);




    至此Zookeeper的原生API的基本操作已将讲完,下一章节主要讲curator框架操作zookeeper



关键字