1.什么是Zookeeper?
它是一个分布式协调框架,是ApacheHadoop的一个子项目,它主要是用来解决分布式应用中经常遇到的一些数据管理问题,如:统一命名服务、状态同步服务、集群管理、分布式应用配置项的管理等。
Zookeeper是一个用于存储少量数据的基于内存的数据库,主要有如下两个核心的概念:文件系统数据结构+监听通知机制。
1.1 文件系统数据结构
每个子目录项都被称作为znode(目录节点),和文件系统类似,我们能够自由的增加、删除znode,在一个znode下增加、删除子znode。
- PERSISTENT持久化目录节点
客户端与zookeeper断开连接后,该节点依旧存在,只要不手动删除该节点,他将永远存在。 - PERSISTENT_SEQUENTIAL持久化顺序编号目录节点
客户端与zookeeper断开连接后,该节点依旧存在,只是Zookeeper给该节点名称进行顺序编号 - EPHEMERAL临时目录节点
客户端与zookeeper断开连接后,该节点被删除 - EPHEMERAL_SEQUENTIAL临时顺序编号目录节点
客户端与zookeeper断开连接后,该节点被删除,只是Zookeeper给该节点名称进行顺序编号 - Container节点(3.5.3版本新增)
如果Container节点下面没有子节点,则Container节点在未来会被Zookeeper自动清除,定时任务默认60s检查一次 - TTL节点(默认禁用,只能通过系统配置zookeeper.extendedTypesEnabled=true开启,不稳定)
过了TTL指定的时间时,被服务器删除。
1.2 监听通知机制
客户端注册监听它关心的任意节点,或者目录节点及递归子目录节点
- 如果注册的是对某个节点的监听,则当这个节点被删除,或者被修改时,对应的客户端将被通知
- 如果注册的是对某个目录的监听,则当这个目录有子节点被创建,或者有子节点被删除,对应的客户端将被通知
- 如果注册的是对某个目录的递归子节点进行监听,则当这个目录下面的任意子节点有目录结构的变化(有子节点被创建,或被删除)或者根节点有数据变化时,对应的客户端将被通知。
所有的通知都是一次性的,及无论是对节点还是对目录进行的监听,一旦触发,对应的监听即被移除。递归子节点,监听是对所有子节点的,所以,每个子节点下面的事件同样只会被触发一次。
2.centos7安装zookeeper
- 配置JAVA环境,检验环境:(未安装java环境的需要自行安装jdk)
//shell
java -version
- 下载解压apache-zookeeper-3.5.10-bin.tar.gz压缩包
//shell
cd /usr/local
//下载
wget https://mirrors.bit.edu.cn/apache/zookeeper/zookeeper-3.5.10/apache-zookeeper-3.5.10-bin.tar.gz
//解压
tar -zxvf apache-zookeeper-3.5.10-bin.tar.gz
- 重命名配置文件zoo_sample.cfg
//进入安装目录
cd apache-zookeeper-3.5.10-bin
//将zoo_sample.cfg复制一份命名为zoo.cfg为后续启动使用
cp ./conf/zoo_sample.cfg ./conf/zoo.cfg
- 启动zookeeper
//启动服务,默认端口2181,修改端口可以到./conf/zoo.cfg文件中修改port
bin/zkServer.sh start conf/zoo.cfg
- 校验是否启动成功
//返回2181监听,启动成功
netstat -an | grep 2181
tcp6 0 0 :::2181 :::* LISTEN
- zookeeper四字监控命令
可参考:zookeeper四字监控命令
3. 使用命令操作zookeeper
- 用zkCli作为客户端连接zookeeper服务端
// /bin/zkCli.sh ‐server ip:port
bin/zkCli.sh ‐server 127.0.0.1:2181
- 查看节点信息,ls 查看目录节点 -R递归子目录节点
[zk: 127.0.0.1:2181(CONNECTED) 5] ls /
[zookeeper]
[zk: 127.0.0.1:2181(CONNECTED) 6] ls /zookeeper
[config, quota]
[zk: 127.0.0.1:2181(CONNECTED) 7] ls -R /
/
/zookeeper
/zookeeper/config
/zookeeper/quota
- 创建节点命令
create [‐s] [‐e] [‐c] [‐tttl] path [data] [acl]
中括号为可选项,没有则默认创建持久化节点
-s:顺序节点
-e:临时节点
-c:容器节点
-t:可以给节点添加过期时间,默认禁用,需要通过系统参数启用
//根目录创建节点名称:dir1 数据为:dir1-data1
[zk: 127.0.0.1:2181(CONNECTED) 10] create /dir1 dir1-data1
Created /dir1
//没有加任何可选参数,创建的就是持久化节点
[zk: 127.0.0.1:2181(CONNECTED) 11] ls /
[dir1, zookeeper]
//查看节点
[zk: 127.0.0.1:2181(CONNECTED) 12] get /dir1
dir1-data1
//修改节点数据:
[zk: 127.0.0.1:2181(CONNECTED) 13] set /dir1 dir1-data1-changed
[zk: 127.0.0.1:2181(CONNECTED) 14] get /dir1
dir1-data1-changed
//查看节点状态信息:
[zk: 127.0.0.1:2181(CONNECTED) 15] stat /dir1
cZxid = 0x4
ctime = Thu Dec 08 14:27:06 CST 2022
mZxid = 0x5
mtime = Thu Dec 08 14:28:54 CST 2022
pZxid = 0x4
cversion = 0
dataVersion = 1
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 18
numChildren = 0
cZxid:创建znode的事务ID(Zxid的值)。
ctime:znode创建时间。
mZxid:最后修改znode的事务ID。
mtime:znode最近修改时间。
pZxid:最后添加或删除子节点的事务ID(子节点列表发生变化才会发生改变)。
cversion:znode的子节点结果集版本(一个节点的子节点增加、删除都会影响这个版本)。
dataVersion:znode的当前数据版本。
aclVersion:表示对此znode的acl版本。
ephemeralOwner:znode是临时znode时,表示znode所有者的sessionID。如果znode不是临时znode,则该字段设置为零。
dataLength:znode数据字段的长度。
numChildren:znode的子znode的数量
查看节点状态信息同时查看数据
[zk: 127.0.0.1:2181(CONNECTED) 21] get -s /dir1
dir1-data1-changed
cZxid = 0x4
ctime = Thu Dec 08 14:27:06 CST 2022
mZxid = 0x7
mtime = Thu Dec 08 14:40:49 CST 2022
pZxid = 0x4
cversion = 0
dataVersion = 3
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 18
numChildren = 0
创建子节点,这里要注意,zookeeper是以节点组织数据的,没有相对路径这么一说,所以,所有的节点一定是以/开头。
[zk: 127.0.0.1:2181(CONNECTED) 22] create /dir1/node1 node1-data1
Created /dir1/node1
[zk: 127.0.0.1:2181(CONNECTED) 25] ls /dir1
[node1]
- 创建临时节点
[zk: 127.0.0.1:2181(CONNECTED) 27] create -e /ephemera1 data1
Created /ephemera1
[zk: 127.0.0.1:2181(CONNECTED) 28] ls /
[dir1, ephemera1, zookeeper]
//临时节点不能创建子节点
[zk: 127.0.0.1:2181(CONNECTED) 29] create -e /ephemera1/dir2 data2
Ephemerals cannot have children: /ephemera1/dir2
- 创建序号节点,加参数-s
//为了容纳子节点,先创建个父目录
[zk: 127.0.0.1:2181(CONNECTED) 37] create /seq‐parent data
Created /seq‐parent
[zk: 127.0.0.1:2181(CONNECTED) 41] create -s /seq‐parent/pre data
Created /seq‐parent/pre0000000000
[zk: 127.0.0.1:2181(CONNECTED) 42] ls /seq‐parent
[pre0000000000]
- 删除节点
语法: delete /节点名
样例:delete /test,delete只能删除不含子节点的节点
deleteall命令:级联删除该节点和子节点。
//因为dir1下存在子节点,所以删除失败
[zk: 127.0.0.1:2181(CONNECTED) 3] delete /dir1
Node not empty: /dir1
//使用deleteall可级联删除该节点和子节点
[zk: 127.0.0.1:2181(CONNECTED) 4] deleteall /dir1
4.事件监听机制
针对节点的监听:一旦事件触发,对应的注册立刻被移除,所以事件监听是一次性的
//注册监听的同时获取数据
get ‐w /path
//对节点进行监听,且获取元数据信息
stat ‐w /path
[zk: 127.0.0.1:2181(CONNECTED) 44] get -w /dir1
dir1-data1-changed
[zk: 127.0.0.1:2181(CONNECTED) 45] set /dir1 data2
WATCHER::
WatchedEvent state:SyncConnected type:NodeDataChanged path:/dir1
针对目录的监听,如下图,目录的变化,会触发事件,且一旦触发,对应的监听也会被移除,后续对节点的创建没有触发监听事件
[zk: 127.0.0.1:2181(CONNECTED) 47] ls -w /dir1
[node1]
[zk: 127.0.0.1:2181(CONNECTED) 48] create /dir1/node2 data2
WATCHER::
WatchedEvent state:SyncConnected type:NodeChildrenChanged path:/dir1
Created /dir1/node2
注意:针对目录的监听,目录的子目录发生变化是监听不到的,需要使用-R递归监听
[zk: 127.0.0.1:2181(CONNECTED) 52] ls -w /dir1
[dir2, node1, node2]
[zk: 127.0.0.1:2181(CONNECTED) 53] create /dir1/dir2/dir3 data3
Created /dir1/dir2/dir3
[zk: 127.0.0.1:2181(CONNECTED) 54] ls -R -w /dir1
/dir1
/dir1/dir2
/dir1/node1
/dir1/node2
/dir1/dir2/dir3
[zk: 127.0.0.1:2181(CONNECTED) 55] create /dir1/dir2/dir3/dir4 data4
WATCHER::
WatchedEvent state:SyncConnected type:NodeChildrenChanged path:/dir1/dir2/dir3
Created /dir1/dir2/dir3/dir4
Zookeeper事件类型:
None:连接建立事件
NodeCreated:节点创建
NodeDeleted:节点删除
NodeDataChanged:节点数据变化
NodeChildrenChanged:子节点列表变化
DataWatchRemoved:节点监听被移除
ChildWatchRemoved:子节点监听被移除
Zookeeper数据的组织形式为一个类似文件系统的数据结构,而这些数据都是存储在内存中的,所以我们可以认为,Zookeeper是一个基于内存的小型数据库