Zk监听机制入门和节点属性信息

zk监听主要是监听:节点创建,节点删除,节点改变、子节点改变
我这里用node-1和node-3同时连接node-1
zk客户端监听功能一般步骤:
1、客户端设置监听事件 命令:get 节点 watch (node-1上操作)
2、执行监听 命令:set 节点 改变内容 (node-3上操作)
3、触发事件、回调事件给客户端 node-1上会回调信息出来
监听机制的应用:高可用的切换,主备的切换

监听机制是一次性的、所以想要持续监听在回调事件之后设再次设置监听事件即可!!

watch机制特点:

一次性触发
事件发生触发监听,一个 watcher event 就会被发送到设置监听的客户端,
这种效果是一次性的,后续再次发生同样的事件,不会再次触发。

事件封装
ZooKeeper 使用 WatchedEvent 对象来封装服务端事件并传递。
WatchedEvent 包含了每一个事件的三个基本属性:
通知状态(keeperState) ,事件类型(EventType)和节点路径(path)

event 异步发送
watcher 的通知事件从服务端发送到客户端是异步的。

先注册再触发
Zookeeper 中的 watch 机制,必须客户端先去服务端注册监听,这样事件发
送才会触发监听,通知给客户端

方式二:java api 操作节点创建
开启idea:创建一个maven工程
导入jar包在pom文件:

<dependency> 
    <groupId>org.apache.zookeeper</groupId> 
    <artifactId>zookeeper</artifactId> 
    <version>3.4.9</version> 
</dependency

代码:

import org.apache.zookeeper.*;

import java.io.IOException;

public class TestZKClient {
    public static void main(String[] args) throws IOException, KeeperException, InterruptedException {
        //通过创建客户端实例:参数(本地系统host文件映射后才能用node,会话超时时间,监听匿名内部类)
   ZooKeeper zk=  new ZooKeeper("node-1:2181,node-2:2181,node-3:2181", 3000, new Watcher() {
            public void process(WatchedEvent watchedEvent) {

            }
        });
   //创建节点(节点名称,数组)
        zk.create("/createbyjava","么么哒".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
        //断开连接
        zk.close();
    }
}

查看:
命令:ls /
查看节点具体信息:get /createbyjava


java操作监听:先注册后监听原则,但是这边没有

public class TestZKClient {
    public static void main(String[] args) throws IOException, KeeperException, InterruptedException {
        //通过创建客户端实例:参数(本地系统host文件映射后才能用node,会话超时时间,监听匿名内部类)
   ZooKeeper zk=  new ZooKeeper("node-1:2181,node-2:2181,node-3:2181", 3000, new Watcher() {
          //process方法就是监听回调客户的处理方法
            public void process(WatchedEvent event) {
                System.out.println("连接的状态为:"+event.getState());
                System.out.println("事件发生的类型:"+event.getType());
                System.out.println("事件发生的路径:"+event.getPath());
            }
        });
   //创建节点(节点名称,数组)
        zk.create("/createbyjava2","么么哒".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
        //断开连接
        zk.close();
    }
}

输出页面:

连接的状态为SyncConnected
事件发生的类型None
事件发生的路径null

原因:

zk的监听事件

- 客户端连接状态监听事件  不需要用户注册满足条件即可触发 
  如果用户关心就去处理 如果不关心可以直接忽略
- 客户端用户自定义监听事件  :先注册再触发  一次性的监听

在这里插入图片描述

java设置监听:

public class TestZKClient {
    public static void main(String[] args) throws IOException, KeeperException, InterruptedException {
        //通过创建客户端实例:参数(本地系统host文件映射后才能用node,会话超时时间,监听匿名内部类)
   ZooKeeper zk=  new ZooKeeper("node-1:2181,node-2:2181,node-3:2181", 3000, new Watcher() {
          //process方法就是监听回调客户的处理方法
            public void process(WatchedEvent event) {
                System.out.println("连接的状态为:"+event.getState());
                System.out.println("事件发生的类型:"+event.getType());
                System.out.println("事件发生的路径:"+event.getPath());
            }
        });
   //创建节点(节点名称,数组)
      //  zk.create("/createbyjava2","么么哒".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
       //设置监听(注意第二个参数,控制是否开启监听)
        zk.getData("/createbyjava",true,null);
        //修改节点数据,满足监听条件(第三个参数表示系统版本号自动维护)
        zk.setData("/createbyjava","呵呵哒".getBytes(),-1);
        //断开连接
        zk.close();
    }
}

输出:

连接的状态为:SyncConnected
事件发生的类型:NodeDataChanged
事件发生的路径:/createbyjava

修改多次也只会输出一次


永久类监听设置:

public class TestZKClient {
    private static   ZooKeeper zk=null;
    public static void main(String[] args) throws IOException, KeeperException, InterruptedException {
        //通过创建客户端实例:参数(本地系统host文件映射后才能用node,会话超时时间,监听匿名内部类)
   zk=  new ZooKeeper("node-1:2181,node-2:2181,node-3:2181", 3000, new Watcher() {
          //process方法就是监听回调客户的处理方法
            public void process(WatchedEvent event) {
                System.out.println("连接的状态为:"+event.getState());
                System.out.println("事件发生的类型:"+event.getType());
                System.out.println("事件发生的路径:"+event.getPath());
            //如果想要实现永久监听在上一个监听结束前再次设置监听
                try {
                    zk.getData("/createbyjava",true,null);
                } catch (KeeperException e) {
                    e.printStackTrace();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
   //创建节点(节点名称,数组)
      //  zk.create("/createbyjava2","么么哒".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
       //设置监听(注意第二个参数,控制是否开启监听)
        zk.getData("/createbyjava",true,null);
        //修改节点数据,满足监听条件(第三个参数表示系统版本号自动维护)
        zk.setData("/createbyjava","呵呵哒".getBytes(),-1);
        zk.setData("/createbyjava","呵呵哒1".getBytes(),-1);
        //判断节点是否存在,设置是否监听
        //zk.exists("/createbyjava2",true);
        //删除节点 版本号自动维护
       // zk.delete("/createbyjava2",-1);


        //断开连接
        zk.close();
    }
}

输出:可以输出多次,

连接的状态为:SyncConnected
事件发生的类型:None
事件发生的路径:null
连接的状态为:SyncConnected
事件发生的类型:NodeDataChanged
事件发生的路径:/createbyjava
连接的状态为:SyncConnected
事件发生的类型:NodeDataChanged
事件发生的路径:/createbyjava

zk从时效性分临时节点和永久节点:

临时节点:节点生命周期将和创建它的客户端的会话相关,客户端断开连接,会话结束,节点消失、

永久节点:该节点和会话没有关系,创建之后一直存在,除非手动强制删除。

临时节点不允许拥有字节点、
节点拥有序列化特性、所以导致zk节点拥有四种类型:
PERSISTENT:永久节点
EPHEMERAL:临时节点
PERSISTENT_SEQUENTIAL:永久节点、序列化
EPHEMERAL_SEQUENTIAL:临时节点、序列
在这里插入图片描述

一般步骤:
1、客户端通过2181连接到zk集群任意机器上,产生会话关系(session)
2、在会话内,客户端可以针对目录树进行增删改查操作
3、操作结束,客户端断开连接 会话结束、

ZooKeeper shell
客户端连接 :开启zk
进入命令行工具
/export/servers/zookeeper/bin/zkCli.sh 连接自己
下面我是用node-3连接node-1的命令:
/export/servers/zookeeper/bin/zkCli.sh -server node-1

查看节点: ls / 命令 (默认会有一个zookeeper节点存在)
在node-3机子上用这个命令也能看到这个节点存在(此处只是想要说明zookeeper的特性:全局数据一致性)

shell的基本操作:节点的增删改查操作
创建节点 create [-s] [-e] path data acl
其中,-s 或-e 分别指定节点特性,顺序或临时节点,若不指定,则表示持
久节点;acl 用来进行权限控制

创建了临时节点之后退出,用另一台机子查看能看到临时节点会稍微停留一会再消失(延时防止网络波动)、
创建一个永久节点之后、不能再次创建、要创建必须加-s序列化特性,

序列化特性用处:控制做事的顺序!

读取节点:
与读取相关的命令有 ls 命令和 get 命令,ls 命令可以列出 Zookeeper 指
定节点下的所有子节点,只能查看指定节点下的第一级的所有子节点;get 命令
可以获取 Zookeeper 指定节点的数据内容和属性信息。
ls path [watch]
get path [watch]
ls2 path [watch]

删除节点 delete path [version]
若删除节点存在子节点,那么无法删除该节点,必须先删除子节点,再删除
父节点。
Rmr path
可以递归删除节点。

更新节点 set path data [version]
data 就是要更新的新内容,version 表示数据版本。

setquota -n|-b val path 对节点增加限制。
n:表示子节点的最大个数
b:表示数据值的最大长度
val:子节点最大个数或数据值的最大长度
path:节点路径

listquota path 列出指定节点的 quota

子节点个数为 2,数据长度-1 表示没限制
delquota [-n|-b] path 删除 quota

节点属性 :
dataVersion:数据版本号,每次对节点进行 set 操作,dataVersion 的值都
会增加 1(即使设置的是相同的数据),可有效避免了数据更新时出现的先后顺
序问题。
cversion :子节点的版本号。当 znode 的子节点有变化时,cversion 的值
就会增加 1。
aclVersion :ACL 的版本号。
cZxid :Znode 创建的事务 id。
mZxid :Znode 被修改的事务 id,即每次对 znode 的修改都会更新 mZxid。

对于 zk 来说,每次的变化都会产生一个唯一的事务 id,zxid(ZooKeeper
Transaction Id)。通过 zxid,可以确定更新操作的先后顺序。例如,如果 zxid1
小于 zxid2,说明 zxid1 操作先于 zxid2 发生,zxid 对于整个 zk 都是唯一的,
即使操作的是不同的 znode。
ctime:节点创建时的时间戳.
mtime:节点最新一次更新发生时的时间戳.
ephemeralOwner:如果该节点为临时节点, ephemeralOwner 值表示与该节点
绑定的 session id. 如果不是, ephemeralOwner 值为 0.
在 client 和 server 通信之前,首先需要建立连接,该连接称为 session。连
接建立后,如果发生连接超时、授权失败,或者显式关闭连接,连接便处于 CLOSED
状态, 此时 session 结束

猜你喜欢

转载自blog.csdn.net/weixin_44654375/article/details/87869443