天天看点

Zookeeper:三、客户端命令前言一、节点信息二、节点类型三、节点操作四、监听器介绍和原理(重要)

前言

Zookeeper的客户端命令详解

文章目录

  • 前言
  • 一、节点信息
  • 二、节点类型
  • 三、节点操作
  • 四、监听器介绍和原理(重要)
    • 4.1 监听操作
    • 4.2 监听原理
    • 4.3 IDEA 客户端操作Zookeeper
    • 4.4 写数据原理

一、节点信息

Zookeeper:三、客户端命令前言一、节点信息二、节点类型三、节点操作四、监听器介绍和原理(重要)

ls -s /

:相应节点的详细信息

[zk: centos1(CONNECTED) 5] ls -s /
[zookeeper]cZxid = 0x0                                # znode被创建时的事务ID
ctime = Thu Jan 01 08:00:00 CST 1970      # znode被创建时的时间
mZxid = 0x0                                                 # znode最后更新的事务ID
mtime = Thu Jan 01 08:00:00 CST 1970     # znode最后修改的时间
pZxid = 0x0                                                  # 最后更新的子节点
cversion = -1                                                # 子节点被修改的次数
dataVersion = 0                                            # znode数据变化版本号
aclVersion = 0                                              # 访问控制列表的变化号
ephemeralOwner = 0x0                               # 如果是临时节点,这个对应znode拥有者的sessionID,如果不是临时节点对应0
dataLength = 0                                            # znode的数据长度
numChildren = 1                                         # znode的子节点数量
           

二、节点类型

Zookeeper:三、客户端命令前言一、节点信息二、节点类型三、节点操作四、监听器介绍和原理(重要)

Zookeeper中的节点包含临时节点和持久节点。

  • 持久节点包括:持久化目录节点、持久化顺序编号目录节点。断开连接后,创建的节点不删除;
  • 临时节点包括:临时目录节点、临时顺序编号目录节点。断开连接后,创建的节点删除;

说明: 在创建znode时设置顺序标识,znode名称后会附加一个值,顺序号是一个单调递增的计数器,由父节点维护。这样使得在分布式系统中,可以利用数据号为所有事件进行全局排序,这样客户端可以通过顺序号推断事件的顺序。

三、节点操作

create 节点路径 节点描述

:创建永久节点(默认);

create -e 节点路径 节点描述

:创建临时节点;

create -s 节点路径 节点描述

:创建带序号的永久节点;

create -s -e 节点路径 节点描述

:创建带序号的临时节点;

set 节点路径 节点描述

:修改节点信息;

ls [-s] [-R] [-w] 节点路径

:获取节点或者节点下面所有节点的信息;

Zookeeper:三、客户端命令前言一、节点信息二、节点类型三、节点操作四、监听器介绍和原理(重要)

delete 节点路径

:删除一个节点

deleteall 节点路径

:删除一个路径上的所有节点

``

四、监听器介绍和原理(重要)

4.1 监听操作

  • 监听节点的值变化

    get -w 节点路径

    :给指定路径添加监听。注意监听注册一次就只能使用一次,其余修改不会再收到通知,必须重新注册。
    Zookeeper:三、客户端命令前言一、节点信息二、节点类型三、节点操作四、监听器介绍和原理(重要)
  • 监听节点的子节点变化(路径变化)

    ls -w 节点路径

    :监听指定节点的子节点变化。同上
    Zookeeper:三、客户端命令前言一、节点信息二、节点类型三、节点操作四、监听器介绍和原理(重要)

4.2 监听原理

  1. 客户端首先创建一个

    main()

    线程;
  2. main()

    线程中创建Zookeeper客户端,这时候会创建两个线程,一个

    listener

    负责监听;一个

    connect

    负责网络连接通信;
  3. 通过

    connect

    线程将注册的监听事件发送给Zookeeper;
  4. 将注册事件存储进服务器端的Zookeeper注册监听器列表中;
  5. Zookeeper如果监听到数据或者路径有变化就将这个消息发送给

    listener

    线程;
  6. listener

    线程内部调用了

    process()

    方法来处理。
    Zookeeper:三、客户端命令前言一、节点信息二、节点类型三、节点操作四、监听器介绍和原理(重要)

4.3 IDEA 客户端操作Zookeeper

  • 环境搭建
<dependencies>
        <!-- junit -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13.1</version>
            <scope>test</scope>
        </dependency>
        <!-- log4j-core -->
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <version>2.13.3</version>
        </dependency>
        <!-- zookeeper -->
        <dependency>
            <groupId>org.apache.zookeeper</groupId>
            <artifactId>zookeeper</artifactId>
            <version>3.5.7</version>
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter</artifactId>
            <version>RELEASE</version>
            <scope>compile</scope>
        </dependency>

    </dependencies>
           
  • 日志配置
log4j.rootLogger=INFO, stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d     %p     [%c]-  %m%n
log4j.appender.logfile=org.apache.log4j.FileAppender
log4j.appender.logfile.File=target/spring.log
           
  • 创建并操纵Zookeeper客户端
public class zkClient {

    private String hostName="192.168.1.6:2181,192.168.1.7:2181,192.168.1.8:2181";
    private ZooKeeper zkCli = null;

    /**
     *     建立连接
     *     public ZooKeeper(String connectString, int sessionTimeout, Watcher watcher) throws IOException {
     *         this(connectString, sessionTimeout, watcher, false);
     *     }
     *     1.连接的服务器名        2.超时时间         3.监视器
     */
    @BeforeEach
    @Test
    public void init() throws Exception {
        System.out.println("初始化.................");
        zkCli = new ZooKeeper(hostName, 60000, new Watcher() {
            public void process(WatchedEvent watchedEvent) {
                List<String> children = null;
                try {
                    children = zkCli.getChildren("/", true);
                    System.out.println("---------------------------");
                    for (String child : children) {
                        System.out.println(child);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
//        zkCli.create("/xuexi","好好学习".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
    }

    /**
     * public String create(String path, byte[] data, List<ACL> acl, CreateMode createMode)
     * 1.路径   2.内容  3.访问权限  4.创建模式
     * 创建子节点
     */
    @Test
    public void createChildren() throws KeeperException, InterruptedException {
        zkCli.create("/xuexi","好好学习".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
        zkCli.create("/xuexi/昨天","摸了一天鱼".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
        zkCli.create("/xuexi/今天","认真学习".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
        zkCli.create("/xuexi/明天","调整好作息,认真对待".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
    }

    /**
     * 1.List<String> getChildren(String path, Watcher watcher):自定义Watcher
     * 2.List<String> getChildren(String path, boolean watch):使用初始化连接时的Watcher
     * 监听子节点
     * 每使用一次下一次都需要进行注册!!!
     */
    @Test
    public void getChildren() throws KeeperException, InterruptedException {
        List<String> children = zkCli.getChildren("/", true);
        System.out.println("---------------------------");
        for (String child : children) {
            System.out.println(child);
        }
    }
           

4.4 写数据原理

  • 写流程将写请求直接发送给Leader节点
    Zookeeper:三、客户端命令前言一、节点信息二、节点类型三、节点操作四、监听器介绍和原理(重要)
    如图,Client 将请求发送给

    ZK Server Leader

    ,Leader写完数据后将数据同步给

    ZK Server Follower1

    。当集群中有半数以上的节点写完数据后,就将结果返回给客户端,因此此时直接由

    ZK Server Leader

    将数据返回给

    Client

    。之后再由

    ZK Server Leader

    同步数据到

    ZK Server Follower2

  • 写流程将写请求直接发送给Follower节点
    Zookeeper:三、客户端命令前言一、节点信息二、节点类型三、节点操作四、监听器介绍和原理(重要)
    Follower接收到节点数据后将数据发送给Leader,然后当前Follower和Leader同时开始同步数据,Leader还需要将数据发送给其他Follower节点进行数据同步,最终集群中有半数以上的节点同步完数据时就返回响应给客户端。