• ZooKeeper学习笔记


    前言

    实际应用中, zookeeper都是使用集群方式安装, 但本文只是入门级演示, 故使用单机版演示.

    集群安装可参考完整版视频教程: 【尚硅谷】大数据技术之Zookeeper 3.5.7版本教程

    安装

    下载

    在官网Release界面下载最新稳定版本
    在这里插入图片描述

    进入后得到http方式的下载地址:https://dlcdn.apache.org/zookeeper/zookeeper-3.7.1/apache-zookeeper-3.7.1-bin.tar.gz

    下载和解压

    #!/bin/bash
    ZK_ROOT_PATH=/opt
    curl -o ${ZK_ROOT_PATH}/zk.tar.gz https://dlcdn.apache.org/zookeeper/zookeeper-3.7.1/apache-zookeeper-3.7.1-bin.tar.gz
    
    tar zxvf ${ZK_ROOT_PATH}/zk.tar.gz -C ${ZK_ROOT_PATH}/
    mv ${ZK_ROOT_PATH}/apache-zookeeper-3.7.1-bin ${ZK_ROOT_PATH}/zk
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    此时ZK_HOME指向了${ZK_ROOT_PATH}/zk, 为了方便管理, 可以在环境变量中设置, 同时将其脚本追加至PATH:

    1. vi ~/.bash_profile

    2. 追加PATH

      # .bash_profile
      
      # Get the aliases and functions
      if [ -f ~/.bashrc ]; then
              . ~/.bashrc
      fi
      
      # User specific environment and startup programs
      ZK_ROOT_PATH=/opt
      ZK_HOME=${ZK_ROOT_PATH}/zk
      PATH=$PATH:${ZK_HOME}/bin:$HOME/.local/bin:$HOME/bin
      
      export PATH
      export ZK_HOME
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
    3. 测试which zkServer.sh

    配置

    zookeeper默认提供了样例, 位于conf/zoo_sample.cfg, 我们将其重命名为zoo.cfg

    主要参数

    参数描述备注
    tickTime通信心跳时间,Zookeeper服务器与客户端心跳时间,单位毫秒
    initLimitLF初始通信时限, Leader和Follower初始连接时能容忍的最多心跳数(tickTime的数量)LF: Leader Follower
    syncLimitLF同步通信时限, Leader和Follower之间通信时间如果超过syncLimit * tickTime,Leader认为Follwer死掉,从服务器列表中删除Follwer。
    dataDir保存Zookeeper中的数据默认的tmp目录,容易被Linux系统定期删除,所以一般不用默认的tmp目录。
    clientPort客户端连接端口,通常不做修改。

    一般只需修改dataDir, 比如改为${ZK_HOME}/data

    mv ${ZK_HOME}/conf/zoo_sample.cfg ${ZK_HOME}/conf/zoo.cfg
    sudo mkdir $ZK_HOME/data
    sed -e 's/dataDir.*/dataDir=${ZK_HOME}\/data/g' -i  ${ZK_HOME}/conf/zoo.cfg
    # 授予当前用户所有权
    sudo chown -R $(whoami):$(whoami) $ZK_HOME
    
    • 1
    • 2
    • 3
    • 4
    • 5

    此时安装已完成, 可以使用zkServer.sh进行操作:

    # 启动
    zkServer.sh start
    # 查看状态
    zkServer.sh stat
    
    • 1
    • 2
    • 3
    • 4

    可以得到输出:

    /usr/bin/java
    ZooKeeper JMX enabled by default
    Using config: /opt/zk/bin/../conf/zoo.cfg
    Client port found: 2181. Client address: localhost. Client SSL: false.
    Mode: standalone
    
    • 1
    • 2
    • 3
    • 4
    • 5

    这表明启动成功了, 并且模式为standalone.

    客户端操作

    连接

    zkCli.sh
    
    • 1

    如果远程连接, 可以使用server指定:

    # zkCli.sh -server 10.99.181.22:2181
    zkCli.sh -server ${host}:${ip}
    
    • 1
    • 2

    命令

    客户端完整命令比较多, 这里列举几个比较常用的

    命令描述备注
    help显示所有操作命令
    ls path使用 ls 命令来查看当前 znode 的子节点 [可监听]
    -w 监听子节点变化
    -s 附加次级信息
    ls /
    create普通创建
    -s 含有序列
    -e 临时(重启或者超时消失)
    get path获得节点的值 [可监听]
    -w 监听节点内容变化
    -s 附加次级信息
    set设置节点的具体值
    stat查看节点状态
    delete删除节点
    deleteall递归删除节点

    节点详细信息

    使用ls -s可以查看节点详细信息, 比如:

    [zk: localhost:2181(CONNECTED) 3] ls -s /
    [zookeeper]
    cZxid = 0x0
    ctime = Thu Jan 01 08:00:00 CST 1970
    mZxid = 0x0
    mtime = Thu Jan 01 08:00:00 CST 1970
    pZxid = 0x0
    cversion = -1
    dataVersion = 0
    aclVersion = 0
    ephemeralOwner = 0x0
    dataLength = 0
    numChildren = 1
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    此处涉及属性描述如下:

    属性描述备注
    czxid创建节点的事务 zxid每次修改 ZooKeeper 状态都会产生一个 ZooKeeper 事务 ID。
    事务 ID 是 ZooKeeper 中所有修改总的次序。
    每次修改都有唯一的 zxid,如果 zxid1 小于 zxid2,
    那么 zxid1 在 zxid2 之前发生。
    ctimeznode 被创建的毫秒数(从 1970 年开始)
    mzxidznode 最后更新的事务 zxid
    mtimeznode 最后修改的毫秒数(从 1970 年开始)
    pZxidznode 最后更新的子节点 zxid
    cversionznode 子节点变化号,znode 子节点修改次数
    dataversionznode 数据变化号
    aclVersionznode 访问控制列表的变化号
    ephemeralOwner如果是临时节点,这个是 znode 拥有者的 session id。如果不是临时节点则是 0。
    dataLengthznode 的数据长度
    numChildrenznode 子节点数量

    节点类型(持久/短暂/有序号/无序号)

    • 持久(Persistent):客户端和服务器端断开连接后,创建的节点不删除
    • 短暂(Ephemeral):客户端和服务器端断开连接后,创建的节点自己删除

    说明:创建znode时设置顺序标识,znode名称后会附加一个值,顺序号是一个单调递增的计数器,由父节点维护

    注意:在分布式系统中,顺序号可以被用于为所有的事件进行全局排序,这样客户端可以通过顺序号推断事件的顺序

    默认情况下, create命令不带任何参数就是创建不带序号持久节点(目录), 如果需要创建临时的, 则加上-e选项, 带序号则加上-s选项:

    # 创建不带序号持久化目录/sanguo
    [zk: localhost:2181(CONNECTED) 5] create /sanguo "diaochan"
    Created /sanguo
    
    # 创建不带序号临时目录
    [zk: localhost:2181(CONNECTED) 24] create -e /sanguo/shu "刘备"
    Created /sanguo/shu
    [zk: localhost:2181(CONNECTED) 25] create -e /sanguo/wei "曹操"
    Created /sanguo/wei
    [zk: localhost:2181(CONNECTED) 26] create -e /sanguo/wu "孙权"
    Created /sanguo/wu
    
    # 创建临时带序号目录
    [zk: localhost:2181(CONNECTED) 19] create -e -s /sanguo/shu "三顾茅庐"
    Created /sanguo/shu0000000001
    [zk: localhost:2181(CONNECTED) 20] create -e -s /sanguo/shu "三顾茅庐"
    Created /sanguo/shu0000000002
    [zk: localhost:2181(CONNECTED) 21] create -e -s /sanguo/shu "三顾茅庐"
    Created /sanguo/shu0000000003
    [zk: localhost:2181(CONNECTED) 23] get /sanguo/shu0000000001
    三顾茅庐
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    监听器原理

    1. 监听原理详解

      1. 首先要有一个main()线程
      2. 在main线程中创建Zookeeper客户端,这时就会创建两个线
        程,一个负责网络连接通信(connet),一个负责监听(listener)。
      3. 通过connect线程将注册的监听事件发送给Zookeeper。
      4. 在Zookeeper的注册监听器列表中将注册的监听事件添加到列表中。
      5. Zookeeper监听到有数据或路径变化,就会将这个消息发送给listener线程。
      6. listener线程内部调用了process()方法。
    2. 常见的监听

      1. 监听节点数据的变化
        get path [watch]
      2. 监听子节点增减的变化
        ls path [watch]

    在这里插入图片描述

    set /sanguo "diaochan"
    # 监听
    get -w /sanguo 
    
    • 1
    • 2
    • 3

    注意:

    注册一次,只能监听一次。想再次监听,需要再次注册。

    客户端API操作

    引入依赖:

    maven

    <dependency>
        <groupId>org.apache.zookeepergroupId>
        <artifactId>zookeeperartifactId>
        <version>3.7.1version>
    dependency>
    <dependency>
        <groupId>org.apache.logging.log4jgroupId>
        <artifactId>log4j-coreartifactId>
        <version>2.17.1version>
    dependency>
    <dependency>
        <groupId>org.apache.logging.log4jgroupId>
        <artifactId>log4j-apiartifactId>
        <version>2.17.1version>
    dependency>
    <dependency>
        <groupId>junitgroupId>
        <artifactId>junitartifactId>
        <version>4.12version>
    dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    java

    private static final String connectString = "192.168.83.168:2181";
        private static final int sessionTimeout = 1000;
    
        public void init() {
            Watcher watcher = watchedEvent -> {
                String path = watchedEvent.getPath();
                log.error(path);
            };
            try (ZooKeeper zooKeeper = new ZooKeeper(connectString, sessionTimeout, watcher)) {
                byte[] data = zooKeeper.getData("/sanguo", watcher, new Stat());
                System.out.println(new String(data, StandardCharsets.UTF_8));
            } catch (InterruptedException | IOException | KeeperException e) {
                e.printStackTrace();
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    如果是多个节点, connectString中使用,分割即可, 不要带空格

    常识

    1. zk的存储类似UNIX, 有一个根结点, 每个节点最大存储1M数据
  • 相关阅读:
    Mybatis中的动态SQL和缓存
    Linux网络--------http协议
    JAVA虚拟机--JVM
    dropbear-ssh2
    数字孪生技术解决方案助力智慧核电建设
    实在没货,软件测试简历咋写?有大佬帮帮忙吗?
    c++架构师需要掌握哪些知识
    网络编程及练习
    降低企业运营成本的API服务有哪些?
    vant实现Select效果--单选和多选
  • 原文地址:https://blog.csdn.net/Young4Dream/article/details/126921017