目录
环境搭建
单机版搭建
集群版搭建
基本语法使用
可视化客户端
数据结构
节点分类
1. 持久节点
2. 临时节点
3. 有序节点
4. 容器节点
5. TTL节点
节点状态
监听机制
watch监听
永久性watch
应用场景
1. 实现分布式锁
2. 乐观锁更新数据
应用场景总结
选举机制
1. 官网下载zookeeper压缩包, 这里用3.8.3版本, 并解压
官网下载地址: Apache ZooKeeper
2. 复制示例配置文件
cp zoo_sample.cfg zoo.cfg
zoo.cfg配置里面参数说明, 不用修改也能启动
# zookeeper基本时间单位,2妙
tickTime=2000
# follower初始化到leader最大时长, 表示tickTime的倍数, 也就是20秒
initLimit=10
# leader和follower同步数据的最大时长, 表示tickTime的倍数, 也就是10秒
syncLimit=5
# 数据和日志存储目录, 也可以配dataLogDir单独指定日志存储目录, 不建议放在默认的/tmp下
dataDir=/tmp/zookeeper
# 对客户端提供端口号
clientPort=2181
# 对单个客户端提供最大连接数
#maxClientCnxns=60
#
# Be sure to read the maintenance section of the
# administrator guide before turning on autopurge.
#
# https://zookeeper.apache.org/doc/current/zookeeperAdmin.html#sc_maintenance
#
# 保存数据的快照数量, 多余的会被清除
#autopurge.snapRetainCount=3
# 自动触发清除任务的时间间隔, 单位小时. 0表示不清除
#autopurge.purgeInterval=1
## Metrics Providers
#
# https://prometheus.io Metrics Exporter
#metricsProvider.className=org.apache.zookeeper.metrics.prometheus.PrometheusMetricsProvider
#metricsProvider.httpHost=0.0.0.0
#metricsProvider.httpPort=7000
#metricsProvider.exportJvmInfo=true
3. 启动zookeeper服务
# 启动, 如果不指定配置文件, 默认找conf/zoo.cfg
bin/zkServer.sh start
# 指定配置文件启动
bin/zkServer.sh start conf/my_zoo.cfg
#查看zookeeper状态
bin/zkServer.sh status
# 关闭服务
bin/zkServer.sh stop
# 重启服务
bin/zkServer.sh restart
4. 客户端连接
# 连接本地zookeeper服务
bin/zkCli.sh
# 连接远程的zookeeper server
bin/zkCli.sh -server ip:port
5. 查看基本命令
5.1 客户端输入help
5.2 官网查看客户端命令
ZooKeeper: Because Coordinating Distributed Systems is a Zoo
6. 增删改查等操作
# 查看/下子节点
ls /
# 新增
create /kk a1
# 修改
set /kk a2
# 查看/kk
get /kk
# 删除
delete /kk
==
命令基本语法 |
功能描述 |
help |
显示所有操作命令 |
ls [-s] [-w] [-R] path |
使用 ls 命令来查看当前 znode 的子节点 [可监听] -w: 监听子节点变化 -s: 节点状态信息(时间戳、版本号、数据大小等) -R: 表示递归的获取 |
create [-s] [-e] [-c] [-t ttl] path [data] [acl] |
创建节点 -s : 创建有序节点。 -e : 创建临时节点。 -c : 创建一个容器节点。 t ttl] : 创建一个TTL节点, -t 时间(单位毫秒)。 data:节点的数据,可选,如果不使用时,节点数据就为null。 acl:访问控制 |
get [-s] [-w] path |
获取节点数据信息 -s: 节点状态信息(时间戳、版本号、数据大小等) -w: 监听节点变化 |
set [-s] [-v version] path data |
设置节点数据 -s:表示节点为顺序节点 -v: 指定版本号 |
getAcl [-s] path |
获取节点的访问控制信息 -s: 节点状态信息(时间戳、版本号、数据大小等) |
setAcl [-s] [-v version] [-R] path acl |
设置节点的访问控制列表 -s:节点状态信息(时间戳、版本号、数据大小等) -v:指定版本号 -R:递归的设置 |
stat [-w] path |
查看节点状态信息 |
delete [-v version] path |
删除某一节点,只能删除无子节点的节点。 -v: 表示节点版本号 |
deleteall path |
递归的删除某一节点及其子节点 |
setquota -n|-b val path |
对节点增加限制 n:表示子节点的最大个数 b:数据值的最大长度,-1表示无限制 |
这里使用prettyZoo, 连接远程zookeeper
zookeeper是 文件系统 + key value 数据结构
ZooKeeper的层次模型称作Data Tree,Data Tree的每个节点叫作Znode。不同于文件系统,每个节点都可以保存数据,每一个 ZNode 默认能够存储 1MB 的数据,每个 ZNode 都可以通过其路径唯一标识,每个节点都有一个版本(version),版本从0开始计数, 可用来CAS实现乐观锁。
zookeeper存在几种不同的节点类型,他们具有不同的生命周期:
类型 |
生命周期 |
创建示例 |
持久节点 (persistent node) |
一直存在,一直存储在ZooKeeper 服务器上,即使创建该节点的客户端与服务端的会话关闭了,该节点依然不会被删除 |
create /locks |
临时节点 (ephemeral node) |
当创建该临时节点的客户端会话因超时或发生异常而关闭时,该节点也相应在 ZooKeeper 服务器上被删除。 |
create -e /locks/DBLock |
有序节点 (sequential node) |
并不算是一种单独种类的节点,而是在之前提到的持久节点和临时节点特性的基础上,增加了一个节点有序的性质。在我们创建有序节点的时候会自动使用一个单调递增的数字作为后缀 |
create -e -s /jobs/job (临时有序节点) |
容器节点 (container node) |
当一个容器节点的最后一个子节点被删除后,容器节点也会被删除 |
create -c /work |
TTL节点 (ttl node) |
当一个TTL节点在 TTL 内没有被修改并且没有子节点,会被删除。注意:默认此功能不开启,需要修改配置文件extendedTypesEnabled=true |
create -t 3000 /ttl_node |
客户端与服务端会话关闭, 或服务端重启, 节点依然存在
client宕机或者client在指定的timeout时间内没有给ZooKeeper集群发消息,节点就会消失
创建方式: -e
# 创建临时节点
create -e /kk-tmp a3
可以和持久节点或临时节点组合
创建方式: -s
Container容器节点(3.5.3版本新增),当容器中没有任何子节点,该容器节点会被zk定期删除(定时任务默认60s 检查一次)。 和持久节点的区别是 ZK 服务端启动后,会有一个单独的线程去扫描,所有的容器节点,当发现容器节点的子节点数量为 0 时,会自动删除该节点。可以用于 leader 或者锁的场景中。
创建方式: -c
# 创建容器节点
create -c /kk-contain aa
带过期时间节点, 当一个TTL节点在 TTL 内没有被修改并且没有子节点,会被删除. 默认禁用。
注意:TTL不能用于临时节点
需要在zoo.cfg中配置extendedTypesEnabled参数
# 开启TTL节点
extendedTypesEnabled=true
创建方式: -t
# 创建ttl节点
create -t 10 /kk-ttl
# 查看节点状态
[zk: localhost:2181(CONNECTED) 35] ls -s /kk
[k1, k2, k3]
cZxid = 0xcd
ctime = Tue Dec 26 03:36:44 CST 2023
mZxid = 0xcd
mtime = Tue Dec 26 03:36:44 CST 2023
pZxid = 0xd1
cversion = 3
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 2
numChildren = 3
参数描述:
zookeeper中的watch机制,必须客户端先去服务端注册监听,这样事件发送才会触发监听,通知给客户端。
支持的事件类型:
命令:
#监听节点数据的变化
get -w /kk
stat -w /kk
#监听子节点增减的变化
ls -w /kk
说明:
特性 |
说明 |
一次性触发 |
watch是一次性的,一旦被触发就会移除,再次使用时需要重新注册 |
客户端顺序回调 |
watch回调是顺序串行执行的,只有回调后客户端才能看到最新的数据状态。一个watcher回调逻辑不应该太多,以免影响别的watch执行 |
轻量级 |
WatchEvent是最小的通信单位,结构上只包含通知状态、事件类型和节点路径,并不会告诉数据节点变化前后的具体内容 |
时效性 |
watcher只有在当前session彻底失效时才会无效,若在session有效期内快速重连成功,则watcher依然存在,仍可接收到通知; |
# 持续监听当前节点的修改和删除事件,以及当前节点的子节点的删除和新增事件
addWatch -m PERSISTENT /kk
# - 持久化递归订阅(默认),在PERSISTENT的基础上,增加了子节点修改的事件触发,以及子节点的子节点的数据变化都会触发相关事件
addWatch -m PERSISTENT_RECURSIVE /kk
多个客户端同时创建临时节点, 只会有一个节点成功. 如果客户端1创建成功, 执行完业务流程后, 释放锁, 也就是删除临时节点, 其他客户端监听该节点删除, 重新竞争锁. 这里用临时节点, 避免客户端宕机情况产生死锁.
# 客户端1
create -c /kk-lock 1
# 客户端2
create -c /kk-lock 1
# 假如客户端1竞争成功, 客户端2创建失败, 客户端2监听该节点
get -w /kk-lock
# 客户端1执行完业务流程后, 释放锁, 删除节点
delete /kk-lock
# 客户端2监听到节点有变动, 重新竞争锁, 创建节点
create -c /kk-lock 1
更新时带上版本号, CAS更新
# 创建节点
create /kt aa
# 查看节点状态(版本号, 创建时间等)
ls -s /kt
# 带版本号更新, 如果版本不匹配则更新失败
set -v 0 /kt bb
==