• Zookeeper(1)-安装与基础使用


    Zookeeper

    服务端

    工作机制

    Zookeeper从设计模式角度来理解:是一个基于观察者模式设计的分布式服务管理框架,它负责存储和管理大家都关心的数据,然后接受观察者的注册,一旦这些数据的状态发生变化,Zookeeper 就将负责通知已经在Zookeeper上注册的那些观察者做出相应的反应。

    Zookeeper = 文件系统 + 通知机制

    特点

    1. Zookeeper:一个领导者(Leader),多个跟随者(Follower)组成的集群。
    2. 集群中只要有半数以上节点存活,Zookeeper集群就能正常服务。所以Zookeeper适合安装奇数台服务器
    3. 全局数据一致:每个Server保存一份相同的数据副本,Client无论连接到哪个Server,数据都是一致的。
    4. 更新请求顺序执行,来自同一个Client的更新请求按其发送顺序依次执行。
    5. 数据更新原子性,一次数据更新要么成功,要么失败。
    6. 实时性,在一定时间范围内,Client能读到最新数据。

    数据结构

    ZooKeeper 数据模型的结构与 Unix 文件系统很类似,整体上可以看作是一棵树,每个 节点称做一个 ZNode。每一个 ZNode 默认能够存储 1MB 的数据,每个 ZNode 都可以通过其路径唯一标识

    图片

    应用场景

    提供的服务包括:统一命名服务、统一配置管理、统一集群管理、服务器节点动态上下线、软负载均衡等。

    统一命名服务

    在分布式环境下,经常需要对应用/服 务进行统一命名,便于识别。

    例如:IP不容易记住,而域名容易记住。

    统一配置管理

    1. 分布式环境下,配置文件同步:

      1. 一般要求一个集群中,所有节点的配置信息是一致的,比如 Kafka 集群。

      2. 对配置文件修改后,希望能够快速同步到各个 节点上。

    2. 配置管理可交由 Zookeeper 实现:

      1. 可将配置信息写入ZooKeeper上的一个Znode。
      2. 各个客户端服务器监听这个Znode。
      3. 一 旦Znode中的数据被修改,ZooKeeper将通知各个客户端服务器。

    统一集群管理

    1. 分布式环境中,实时掌握每个节点的状态是必要的。
      1. 可根据节点实时状态做出一些调整。
    2. ZooKeeper可以实现实时监控节点状态变化
      1. 可将节点信息写入ZooKeeper上的一个ZNode。
      2. 监听这个ZNode可获取它的实时状态变化。

    Zookeeper 安装

    下载ZooKeeper:从Zookeeper 镜像下载地址中选择对应的版本进行下载;

    解压:tar -zxvf zookeeper-3.4.5.tar.gz 重命名:mv zookeeper-3.4.5 zk

    Zookeeper 参数详解

    复制代码
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    # 通信心跳时间,Zookeeper服务器与客户端心跳时间,单位毫秒 tickTime=2000 # LF初始通信时限 # Leader 和 Follower 初始连接时能容忍的最多心跳数(tickTime 的数量) initLimit=10 # LF 同步通信时限 # Leader 和 Follower 之间通信时间如果超过 syncLimit * tickTime,leader 认为 Follower 死掉,从服务器列表中删除 Follower syncLimit=5 # 保存 Zookeeper 中的数据 # 默认存放在 tmp 目录,容易被 Linux 系统定期删除,所以一般不用默认的 tmp 目录 dataDir=/opt/module/zookeeper-3.5.7/zkData # 客户端连接端口,通常不做修改 clientPort=2181

    Zookeeper 集群配置

    配置

    添加服务器编号的配置文件,在配置文件中 dataDir=/opt/module/zookeeper-3.5.7/zkData 下创建 myid 文件,在文件中添加与 server 对应的编号

    修改配置文件,在 bin/zoo_sample.cfg 后面追加对应主机的配置信息,每一台主机对应的配置文件都要进行修改。

    复制代码
    • 1
    • 2
    • 3
    server.2=192.168.3.19:2888:3888 server.3=192.168.3.33:2888:3888 server.4=192.168.3.34:2888:3888

    配置文件详解

    复制代码
    • 1
    server.A=B:C:D

    A:是一个数据,表示这是几号服务器,对应每台服务器创建的 myid 里面的数字;Zookeeper 启动时读取此文件,拿到里面的数据与 zoo.cfg 里面的配置信息比 较从而判断到底是哪个 server

    B:对应的服务器地址;

    C:是这个服务器 Follower 与集群中的 Leader 服务器交换信息的端口;

    D:是万一集群中的 Leader 服务器挂了,需要一个端口来重新进行选举,选出一个新的 Leader,而这个端口就是用来执行选举时服务器相互通信的端口。

    运行

    分别启动对应的 Zookeeper,我这边配置的是三台Zookeeper服务器;

    启动第一台的 Zookeeper 的状态:

    复制代码
    • 1
    • 2
    • 3
    • 4
    • 5
    [root@localhost zookeeper-3.5.7]# sh ./bin/zkServer.sh status ZooKeeper JMX enabled by default Using config: /opt/module/zookeeper-3.5.7/bin/../conf/zoo.cfg Client port found: 2181. Client address: localhost. Error contacting service. It is probably not running.

    此时提示 Error contacting service. It is probably not running. 因为现在还只启动一台 Zookeeper,不满足 半数以上 的节点存活,所以现在不能正常提供服务。

    后面依次启动对应的 Zookeeper 服务。

    第二台启动与对应的状态

    复制代码
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    [root@localhost zookeeper-3.5.7]# sh ./bin/zkServer.sh start ZooKeeper JMX enabled by default Using config: /opt/module/zookeeper-3.5.7/bin/../conf/zoo.cfg Starting zookeeper ... STARTED [root@localhost zookeeper-3.5.7]# sh ./bin/zkServer.sh status ZooKeeper JMX enabled by default Using config: /opt/module/zookeeper-3.5.7/bin/../conf/zoo.cfg Client port found: 2181. Client address: localhost. Mode: leader

    第三台启动与对应的状态

    复制代码
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    [root@localhost zookeeper-3.5.7]# sh ./bin/zkServer.sh start ZooKeeper JMX enabled by default Using config: /opt/module/zookeeper-3.5.7/bin/../conf/zoo.cfg Starting zookeeper ... STARTED [root@localhost zookeeper-3.5.7]# sh ./bin/zkServer.sh status ZooKeeper JMX enabled by default Using config: /opt/module/zookeeper-3.5.7/bin/../conf/zoo.cfg Client port found: 2181. Client address: localhost. Mode: follower

    第一台服务器的状态

    复制代码
    • 1
    • 2
    • 3
    • 4
    • 5
    [root@localhost zookeeper-3.5.7]# sh ./bin/zkServer.sh status ZooKeeper JMX enabled by default Using config: /opt/module/zookeeper-3.5.7/bin/../conf/zoo.cfg Client port found: 2181. Client address: localhost. Mode: follower

    到这里 Zookeeper 集群的配置与启动就搞定了。

    Zookeeper 的选举机制

    第一次启动的时候

    以我上面的三个 Zookeeper 服务器集群为例:

    1. 服务器1启动,发起一次选举。服务器1投自己一票。此时服务器1票数一票,不够半数以上(2票),选举无法完成,服务器1状态保持为 LOOKING;

      b4RjZ6.png

    2. 服务器2启动,再发起一次选举。服务器1和2分别投自己一票并交换选票信息:此时服务器1发现服务器2的myid比自己目前投票推举的(服务器1) 大,更改选票为推举服务器2。此时服务器1票数0票,服务器2票数2票,此时服务器2的票数已经超过半数,服务器2当选Leader。服务器1更改状态为FOLLOWING,服务器2更改状态为LEADING;

      b4WQQs.png

    3. 服务器3启动,发起一次选举。此时服务器1,2已经不是LOOKING状态,不会更改选票信息。交换选票信息结果:服务器2为2票,服务器3为 1票。此时服务器3服从多数,更改选票信息为服务器2,并更改状态为FOLLOWING;

      b4WBO1.png

    非第一次启动的时候

    这里首先还要先讲出关于Zookeeper集群Client端的一些其他概念:

    b4fKAK.md.png

    SID服务器ID。用来唯一标识一台 ZooKeeper集群中的机器,每台机器不能重复,和 myid 一致。

    ZXID事务idZXID是一个事务ID,用来标识一次服务器状态的变更。在某一时刻, 集群中的每台机器的ZXID值不一定完全一 致,这和 ZooKeeper 服务器对于客户端 更新请求 的处理逻辑有关。

    Epoch每个Leader任期的代号。没有Leader时同一轮投票过程中的逻辑时钟值是相同的。每投完一次票这个数据就会增加。

    Zookeeper 会发生选举的场景
    • 服务器初始化启动(上面描述了)
    • 服务器运行期间无法和 Leader 保持连接
    一台服务器进入选举的两种状态
    1. 集群中本来就已经存在一个 Leader:

      机器试图去选举Leader时,会被告知当前服务器的Leader信息,对于该机器来说,仅仅需要和Leader机器建立连 接,并进行状态同步即可。

    2. 集群中确实不存在 Leader

      假设ZooKeeper由5台服务器组成,SID分别为1、2、3、4、5,ZXID分别为8、8、8、7、7,并且此时SID为3的服务器是Leader。某一时刻, 3和5服务器出现故障,因此开始进行Leader选举。

      1(EPOCH,ZXID,SID ) 2(EPOCH,ZXID,SID ) 4(EPOCH,ZXID,SID )
      SID 为 1、2、4 的机器投票情况 (1,8,1) (1,8,2) (1,7,4)

      选举规则:

      1. EPOCH大的直接胜出;
      2. EPOCH相同,事务id大的胜出
      3. 事务id相同,服务器id大的胜出;

    集群启动脚本

    复制代码
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    #!/bin/bash case $1 in "start"){ for i in 192.168.3.19 192.168.3.33 192.168.3.34 do echo ----------- zookeeper $i 启动 ------------- ssh $i "/opt/module/zookeeper-3.5.7/bin/zkServer.sh start" done } ;; "stop"){ for i in 192.168.3.19 192.168.3.33 192.168.3.34 do echo ----------- zookeeper $i 停止 ------------- ssh $i "/opt/module/zookeeper-3.5.7/bin/zkServer.sh stop" done } ;; "status"){ for i in 192.168.3.19 192.168.3.33 192.168.3.34 do echo ----------- zookeeper $i 状态 ------------- ssh $i "/opt/module/zookeeper-3.5.7/bin/zkServer.sh status" done } ;; esac

    启动脚本是建立在机器之前的无密远程登录设置好的前提下,如果没有设置好的话,在执行的过程中需要输入对应的密码。

    复制代码
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    [root@localhost ~]# sh zk.sh start ----------- zookeeper 192.168.3.19 启动 ------------- /usr/bin/java ZooKeeper JMX enabled by default Using config: /opt/module/zookeeper-3.5.7/bin/../conf/zoo.cfg Starting zookeeper ... STARTED ----------- zookeeper 192.168.3.33 启动 ------------- /usr/bin/java ZooKeeper JMX enabled by default Using config: /opt/module/zookeeper-3.5.7/bin/../conf/zoo.cfg Starting zookeeper ... STARTED ----------- zookeeper 192.168.3.34 启动 ------------- /usr/bin/java ZooKeeper JMX enabled by default Using config: /opt/module/zookeeper-3.5.7/bin/../conf/zoo.cfg Starting zookeeper ... STARTED [root@localhost ~]# sh zk.sh status ----------- zookeeper 192.168.3.19 状态 ------------- /usr/bin/java ZooKeeper JMX enabled by default Using config: /opt/module/zookeeper-3.5.7/bin/../conf/zoo.cfg Client port found: 2181. Client address: localhost. Mode: follower ----------- zookeeper 192.168.3.33 状态 ------------- /usr/bin/java ZooKeeper JMX enabled by default Using config: /opt/module/zookeeper-3.5.7/bin/../conf/zoo.cfg Client port found: 2181. Client address: localhost. Mode: leader ----------- zookeeper 192.168.3.34 状态 ------------- /usr/bin/java ZooKeeper JMX enabled by default Using config: /opt/module/zookeeper-3.5.7/bin/../conf/zoo.cfg Client port found: 2181. Client address: localhost. Mode: follower [root@localhost ~]# sh zk.sh stop ----------- zookeeper 192.168.3.19 停止 ------------- /usr/bin/java ZooKeeper JMX enabled by default Using config: /opt/module/zookeeper-3.5.7/bin/../conf/zoo.cfg Stopping zookeeper ... STOPPED ----------- zookeeper 192.168.3.33 停止 ------------- /usr/bin/java ZooKeeper JMX enabled by default Using config: /opt/module/zookeeper-3.5.7/bin/../conf/zoo.cfg Stopping zookeeper ... STOPPED ----------- zookeeper 192.168.3.34 停止 ------------- /usr/bin/java ZooKeeper JMX enabled by default Using config: /opt/module/zookeeper-3.5.7/bin/../conf/zoo.cfg Stopping zookeeper ... STOPPED

    客户端

    基本语法

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

    启动客户端

    先进入 Zookeeper 的安装目录:

    复制代码
    • 1
    bin/zkCli.sh -server 192.168.3.34

    znode 节点数据信息

    查看当前 znode 中所有包含的内容

    复制代码
    • 1
    • 2
    [zk: 192.168.3.34(CONNECTED) 2] ls / [zookeeper]

    查看当前 znode 中所有包含的详细内容

    复制代码
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    [zk: 192.168.3.34(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. czxid:创建节点的事务 zxid

    每次修改 ZooKeeper 状态都会产生一个 ZooKeeper 事务 ID。事务 ID 是 ZooKeeper 中所 有修改总的次序。每次修改都有唯一的 zxid,如果 zxid1 小于 zxid2,那么 zxid1 在 zxid2 之 前发生。

    1. ctime:znode 被创建的毫秒数(从 1970 年开始)
    2. mzxid:znode 最后更新的事务 zxid
    3. mtime:znode 最后修改的毫秒数(从 1970 年开始)
    4. pZxid:znode 最后更新的子节点 zxid
    5. cversion:znode 子节点变化号,znode 子节点修改次数
    6. dataversion:znode 数据变化号
    7. aclVersion:znode 访问控制列表的变化号
    8. ephemeralOwner:如果是临时节点,这个是 znode 拥有者的 session id。如果不是 临时节点则是 0。
    9. dataLength:znode 的数据长度
    10. numChildren:znode 子节点数量

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

    简介

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

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

    (1)持久化目录节点:客户端与Zookeeper断开连接后,该节点依旧存在

    (2)持久化顺序编号目录节点:客户端与Zookeeper断开连接后,该节点依旧存 在,只是Zookeeper给该节点名称进行顺序编号

    (3)临时目录节点:客户端与Zookeeper断开连接后,该节点被删除

    (4)临时顺序编号目录节点:客户端与 Zookeeper 断开连接后 , 该 节 点 被 删 除 , 只 是 Zookeeper给该节点名称进行顺序编号。

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

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

    实操

    持久节点无序号
    创建节点
    复制代码
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    [zk: 192.168.3.34(CONNECTED) 4] create /lol "luoshou" Created /lol [zk: 192.168.3.34(CONNECTED) 5] ls / [lol, zookeeper] [zk: 192.168.3.34(CONNECTED) 7] create /lol/noxus "delaiwen" Created /lol/noxus [zk: 192.168.3.34(CONNECTED) 8] ls / [lol, zookeeper] [zk: 192.168.3.34(CONNECTED) 9] ls /lol [noxus]
    获取节点的值
    复制代码
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    [zk: 192.168.3.34(CONNECTED) 11] get -s /lol luoshou cZxid = 0x500000002 ctime = Thu Mar 10 23:58:31 CST 2022 mZxid = 0x500000002 mtime = Thu Mar 10 23:58:31 CST 2022 pZxid = 0x500000003 cversion = 1 dataVersion = 0 aclVersion = 0 ephemeralOwner = 0x0 dataLength = 7 numChildren = 1
    持久节点有序号
    创建节点
    复制代码
    • 1
    • 2
    • 3
    • 4
    [zk: 192.168.3.34(CONNECTED) 1] create -s /lol/demacia "dema" Created /lol/demacia0000000001 [zk: 192.168.3.34(CONNECTED) 5] create -s /lol/demacia "dema" Created /lol/demacia0000000002
    获取节点的值
    复制代码
    • 1
    • 2
    • 3
    • 4
    [zk: 192.168.3.34(CONNECTED) 4] ls /lol [demacia0000000001, noxus] [zk: 192.168.3.34(CONNECTED) 6] ls /lol [demacia0000000001, demacia0000000002, noxus]
    临时节点无序号
    创建节点
    复制代码
    • 1
    • 2
    [zk: 192.168.3.34(CONNECTED) 1] create -e /lol/zaun "mengduo" Created /lol/zaun
    获取节点的值
    复制代码
    • 1
    • 2
    [zk: 192.168.3.34(CONNECTED) 4] ls /lol [demacia0000000001, demacia0000000002, noxus, zaun]
    临时节点有序号
    创建节点
    复制代码
    • 1
    • 2
    [zk: 192.168.3.34(CONNECTED) 8] create -e -s /lol/zaun "mengduo" Created /lol/zaun0000000004
    获取节点的值
    复制代码
    • 1
    • 2
    [zk: 192.168.3.34(CONNECTED) 11] ls /lol [demacia0000000001, demacia0000000002, noxus, zaun, zaun0000000004]
    退出客户端后再启动查看

    重启后临时节点已经无了:

    复制代码
    • 1
    • 2
    [zk: 192.168.3.34(CONNECTED) 0] ls /lol [demacia0000000001, demacia0000000002, noxus]
    修改节点中的值
    复制代码
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    [zk: 192.168.3.34(CONNECTED) 1] get -s /lol/noxus delaiwen cZxid = 0x500000003 ctime = Fri Mar 11 00:00:07 CST 2022 mZxid = 0x500000003 mtime = Fri Mar 11 00:00:07 CST 2022 pZxid = 0x500000003 cversion = 0 dataVersion = 0 aclVersion = 0 ephemeralOwner = 0x0 dataLength = 8 numChildren = 0 [zk: 192.168.3.34(CONNECTED) 2] set -s /lol/noxus "luoshou" cZxid = 0x500000003 ctime = Fri Mar 11 00:00:07 CST 2022 mZxid = 0x50000000f mtime = Fri Mar 11 00:22:40 CST 2022 pZxid = 0x500000003 cversion = 0 dataVersion = 1 aclVersion = 0 ephemeralOwner = 0x0 dataLength = 7 numChildren = 0 [zk: 192.168.3.34(CONNECTED) 3] get -s /lol/noxus luoshou cZxid = 0x500000003 ctime = Fri Mar 11 00:00:07 CST 2022 mZxid = 0x50000000f mtime = Fri Mar 11 00:22:40 CST 2022 pZxid = 0x500000003 cversion = 0 dataVersion = 1 aclVersion = 0 ephemeralOwner = 0x0 dataLength = 7 numChildren = 0

    监听器

    简介

    客户端注册监听它关心的目录节点,当目录节点发生变化(数据改变、节点删除、子目 录节点增加删除)时,ZooKeeper 会通知客户端。监听机制保证 ZooKeeper 保存的任何的数 据的任何改变都能快速的响应到监听了该节点的应用程序。

    原理

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

    bIasne.md.png

    常见的监听

    1. 监听节点数据的变化

      get path [watch]

    2. 监听子节点增减的变化

      ls path [watch]

    实操

    节点值变化的监听

    四号机器注册监听

    复制代码
    • 1
    • 2
    [zk: localhost:2181(CONNECTED) 4] get -w /lol luoshou

    三号机器修改对应节点的数值

    复制代码
    • 1
    [zk: 192.168.3.34(CONNECTED) 4] set /lol "delaiwen"

    四号机器触发监听

    复制代码
    • 1
    • 2
    • 3
    • 4
    [zk: localhost:2181(CONNECTED) 5] WATCHER:: WatchedEvent state:SyncConnected type:NodeDataChanged path:/lol
    节点的子节点变化的监听(路径变化)

    四号机器注册监听

    复制代码
    • 1
    • 2
    [zk: localhost:2181(CONNECTED) 5] ls -w /lol [demacia0000000001, demacia0000000002, noxus]

    三号机器修改对应节点,创建新的子节点

    复制代码
    • 1
    • 2
    [zk: 192.168.3.34(CONNECTED) 5] create /lol/yordles "timo" Created /lol/yordles

    四号机器触发监听

    复制代码
    • 1
    • 2
    • 3
    • 4
    [zk: localhost:2181(CONNECTED) 6] WATCHER:: WatchedEvent state:SyncConnected type:NodeChildrenChanged path:/lol

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

    节点删除

    复制代码
    • 1
    • 2
    • 3
    • 4
    # 删除单节点 [zk: localhost:2181(CONNECTED) 7] delete /lol/yordles # 删除有子节点的节点 [zk: localhost:2181(CONNECTED) 9] deleteall /lol

    客户端 API

    前提是 Zookeeper 的服务已经启动了。

    创建 zookeeper 的 mavne 项目。

    导入 pom.xml 文件:

    复制代码
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>RELEASE</version> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> <version>2.8.2</version> </dependency> <dependency> <groupId>org.apache.zookeeper</groupId> <artifactId>zookeeper</artifactId> <version>3.5.7</version> </dependency> </dependencies>

    导入 log4j 的配置文件

    复制代码
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    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 log4j.appender.logfile.layout=org.apache.log4j.PatternLayout log4j.appender.logfile.layout.ConversionPattern=%d %p [%c]- %m%n

    Zookeeper 客户端 API 的一些基础操作

    复制代码
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    public class ZkClient { /** * 服务器地址 * */ private String connectString = "192.168.3.33:2181,192.168.3.34:2128,192.168.3.19:2181"; /** * 超时时间 * */ private int sessionTimout = 2000; public ZooKeeper zooKeeper; /** * 初始化操作,连接 Zookeeper 集群。 * */ @Before public void init() { ZKClientConfig config = new ZKClientConfig(); config.setProperty(ZKClientConfig.ENABLE_CLIENT_SASL_KEY, "false"); try { zooKeeper = new ZooKeeper(connectString, sessionTimout, new Watcher() { @Override public void process(WatchedEvent watchedEvent) { System.out.println("----------------------------"); List <String> children = null; try { children = zooKeeper.getChildren("/", true); } catch (KeeperException e) { e.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace(); } for (String child : children) { System.out.println(child); } System.out.println("----------------------------"); } }, config); } catch (IOException e) { e.printStackTrace(); } } /** * 创建子节点 * */ @Test public void create() throws KeeperException, InterruptedException { String nodeCreate = zooKeeper.create("/lol", "lubu".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT); } /** * 创建监听 * */ @Test public void getChildren() throws KeeperException, InterruptedException { List<String> children = zooKeeper.getChildren("/", true); for (String child : children) { System.out.println(child); } // 延迟 Thread.sleep(Integer.MAX_VALUE); } /** * 判断节点是否存在 * */ @Test public void exist() throws KeeperException, InterruptedException { Stat exists = zooKeeper.exists("/lol", false); System.out.println(exists == null ? "not exit" : exists); } }
  • 相关阅读:
    软件测试的调用接口怎么调用,逻辑是什么?
    javaScript之数组中reduce的详细介绍及使用
    运算符【详细】
    Python中dataframe.groupby()根据数据属性对数据分组
    腾讯云学生专享云服务器介绍及购买攻略
    <TypeScript系列>:常量断言 as const
    我只说一遍!这几个程序员都在用的接单平台还不赶快收藏好!!!
    RocketMQ部署
    Nacos注册中心配置安装和问题解决
    数据仓库之BI
  • 原文地址:https://www.cnblogs.com/lhnstart/p/15994170.html