大数据-Zookeeper
- 2019 年 12 月 25 日
- 筆記
7 Zookeeper
7.1 Zookeeper 的概述
- Zookeeper 是一个开源的分布式协调服务框架 ,主要用来解决分布式集群中 应用系统的一致性问题
- Zookeeper 是 Google Chubby 思想的一个开源实现
- Zookeeper 本质上是一个分布式文件系统, 适合存放小文件, 通过文件系统来实现分布式协调
分布式文件系统?

- 在上图左侧, Zookeeper 中存储的其实是一个又一个 Znode, Znode 是 Zookeeper 中的节点
- Znode 是有路径的, 例如
/data/host1
,/data/host2
, 这个路径也可以理解为是 Znode 的 Name - Znode 也可以携带数据, 例如说某个 Znode 的路径是
/data/host1
, 其值是一个字符串"192.168.0.1"
- Znode 是有路径的, 例如
- 正因为 Znode 的特性, 所以 Zookeeper 可以对外提供出一个类似于文件系统的试图, 可以通过操作文件系统的方式操作 Zookeeper
- 使用路径获取 Znode
- 获取 Znode 携带的数据
- 修改 Znode 携带的数据
- 删除 Znode
- 添加 Znode
- 等等…
Zookeeper 是分布式的
首先呢, Zookeeper 是分为服务端和客户端的, 客户端有 Java 的客户端, 有 Shell 命令行的客户端等, 客户端通过一个类似于文件系统的 API 来访问 Zookeeper 集群

但是事实上, 客户端最终是直接访问 Zookeeper 集群, 集群中有两大类角色, 一类是 Leader, 一类是 Follower, 其实就是主从, Leader 负责读和写, Follower 只能读, 遇到会产生修改的请求会转发给 Leader 处理, 这是因为 Zookeeper 本质上就是为了在分布式环境中对消息的一致性的支持, 而 Zookeeper 所基于的 ZAB 协议是 Paxos 协议的一个变种, ZAB 协议中是有一个全局的事务生成者, 就是 Leader, 修改设计到在分布式环境下对事务达成一致, 必须由 Leader 发起
举个例子?
比如说一个常见的分布式主从系统, 如果有 ZK 在的话, 主节点不需要和每个从节点保持连接, 只需要监听从节点创建的 Znode, 便可以知道谁在线
Zookeeper 能做什么?
- 发布订阅
- 命名服务
- 分布式锁
- 分布式协调
7.2 Zookeeper安装
服务器IP |
主机名 |
myid的值 |
---|---|---|
192.168.174.100 |
node01 |
1 |
192.168.174.110 |
node02 |
2 |
192.168.174.120 |
node03 |
3 |
第一步:下载zookeeeper的压缩包,下载网址如下
http://archive.apache.org/dist/zookeeper/
我们在这个网址下载我们使用的zk版本为3.4.9
下载完成之后,上传到我们的linux的/export/softwares路径下准备进行安装
第二步:解压
解压zookeeper的压缩包到/export/servers路径下去,然后准备进行安装
cd /export/software tar -zxvf zookeeper-3.4.9.tar.gz -C ../servers/
第三步:修改配置文件
第一台机器修改配置文件
cd /export/servers/zookeeper-3.4.9/conf/ cp zoo_sample.cfg zoo.cfg mkdir -p /export/servers/zookeeper-3.4.9/zkdatas/
vim zoo.cfg
dataDir=/export/servers/zookeeper-3.4.9/zkdatas # 保留多少个快照 autopurge.snapRetainCount=3 # 日志多少小时清理一次 autopurge.purgeInterval=1 # 集群中服务器地址 server.1=node01:2888:3888 server.2=node02:2888:3888 server.3=node03:2888:3888
第四步:添加myid配置
在第一台机器的
/export/servers/zookeeper-3.4.9/zkdatas /这个路径下创建一个文件,文件名为myid ,文件内容为1
echo 1 > /export/servers/zookeeper-3.4.9/zkdatas/myid
第五步:安装包分发并修改myid的值
安装包分发到其他机器
第一台机器上面执行以下两个命令
scp -r /export/servers/zookeeper-3.4.9/ node02:/export/servers/
scp -r /export/servers/zookeeper-3.4.9/ node03:/export/servers/
第二台机器上修改myid的值为2
echo 2 > /export/servers/zookeeper-3.4.9/zkdatas/myid

第三台机器上修改myid的值为3
echo 3 > /export/servers/zookeeper-3.4.9/zkdatas/myid

第六步:三台机器启动zookeeper服务
三台机器启动zookeeper服务
这个命令三台机器都要执行
/export/servers/zookeeper-3.4.9/bin/zkServer.sh start
查看启动状态
/export/servers/zookeeper-3.4.9/bin/zkServer.sh status
7.3 Zookeeper的Shell 客户端操作
命令 |
说明 |
参数 |
---|---|---|
create [-s] [-e] path data acl |
创建Znode |
-s 指定是顺序节点-e 指定是临时节点 |
ls path [watch] |
列出Path下所有子Znode |
|
get path [watch] |
获取Path对应的Znode的数据和属性 |
|
ls2 path [watch] |
查看Path下所有子Znode以及子Znode的属性 |
|
set path data [version] |
更新节点 |
version 数据版本 |
delete path [version] |
删除节点, 如果要删除的节点有子Znode则无法删除 |
version 数据版本 |
rmr path |
删除节点, 如果有子Znode则递归删除 |
|
setquota -n|-b val path |
修改Znode配额 |
-n 设置子节点最大个数-b 设置节点数据最大长度 |
history |
列出历史记录 |
|
1:创建普通节点
create /app1 hello
2: 创建顺序节点
create -s /app3 world
3:创建临时节点
create -e /tempnode world
4:创建顺序的临时节点
create -s -e /tempnode2 aaa
5:获取节点数据
get /app1
6:修改节点数据
set /app1 xxx
7:删除节点
delete /app1 删除的节点不能有子节点
rmr /app1 递归删除
Znode 的特点
- 文件系统的核心是
Znode
- 如果想要选取一个
Znode
, 需要使用路径的形式, 例如/test1/test11
- Znode 本身并不是文件, 也不是文件夹, Znode 因为具有一个类似于 Name 的路径, 所以可以从逻辑上实现一个树状文件系统
- ZK 保证 Znode 访问的原子性, 不会出现部分 ZK 节点更新成功, 部分 ZK 节点更新失败的问题
Znode
中数据是有大小限制的, 最大只能为1M
Znode
是由三个部分构成stat
: 状态, Znode的权限信息, 版本等data
: 数据, 每个Znode都是可以携带数据的, 无论是否有子节点children
: 子节点列表
Znode 的类型
- 每个
Znode
有两大特性, 可以构成四种不同类型的Znode
- 持久性
持久
客户端断开时, 不会删除持有的Znode临时
客户端断开时, 删除所有持有的Znode, 临时Znode不允许有子Znode
- 顺序性
有序
创建的Znode有先后顺序, 顺序就是在后面追加一个序列号, 序列号是由父节点管理的自增无序
创建的Znode没有先后顺序
- 持久性
Znode
的属性dataVersion
数据版本, 每次当Znode
中的数据发生变化的时候,dataVersion
都会自增一下cversion
节点版本, 每次当Znode
的节点发生变化的时候,cversion
都会自增aclVersion
ACL(Access Control List)
的版本号, 当Znode
的权限信息发生变化的时候aclVersion会自增zxid
事务IDctime
创建时间mtime
最近一次更新的时间ephemeralOwner
如果Znode
为临时节点,ephemeralOwner
表示与该节点关联的SessionId
通知机制
- 通知类似于数据库中的触发器, 对某个Znode设置
Watcher
, 当Znode发生变化的时候,WatchManager
会调用对应的Watcher
- 当Znode发生删除, 修改, 创建, 子节点修改的时候, 对应的
Watcher
会得到通知 Watcher
的特点- 一次性触发 一个
Watcher
只会被触发一次, 如果需要继续监听, 则需要再次添加Watcher
- 事件封装:
Watcher
得到的事件是被封装过的, 包括三个内容keeperState, eventType, path
- 一次性触发 一个
KeeperState |
EventType |
触发条件 |
说明 |
---|---|---|---|
|
None |
连接成功 |
|
SyncConnected |
NodeCreated |
Znode被创建 |
此时处于连接状态 |
SyncConnected |
NodeDeleted |
Znode被删除 |
此时处于连接状态 |
SyncConnected |
NodeDataChanged |
Znode数据被改变 |
此时处于连接状态 |
SyncConnected |
NodeChildChanged |
Znode的子Znode数据被改变 |
此时处于连接状态 |
Disconnected |
None |
客户端和服务端断开连接 |
此时客户端和服务器处于断开连接状态 |
Expired |
None |
会话超时 |
会收到一个SessionExpiredException |
AuthFailed |
None |
权限验证失败 |
会收到一个AuthFailedException |
会话
- 在ZK中所有的客户端和服务器的交互都是在某一个
Session
中的, 客户端和服务器创建一个连接的时候同时也会创建一个Session
Session
会在不同的状态之间进行切换:CONNECTING
,CONNECTED
,RECONNECTING
,RECONNECTED
,CLOSED
- ZK中的会话两端也需要进行心跳检测, 服务端会检测如果超过超时时间没收到客户端的心跳, 则会关闭连接, 释放资源, 关闭会话