数据结构
- 基本结构
以znode为数据节点的层次化的多叉树形结构,每个znode由stat(状态信息)和data(具体数据)组成

- znode 4 种类型
- 持久(PERSISTENT)节点 :一旦创建就一直存在即使 ZooKeeper 集群宕机,直到将其删除。
- 临时(EPHEMERAL)节点 :临时节点的生命周期是与 客户端会话(session) 绑定的,会话消失则节点消失 。并且,临时节点只能做叶子节点 ,不能创建子节点。这一特点在分布式中非常有用,比如很多中间件将zookeeper作为服务中心,临时节点有很大的功劳,比如中间件一个节点下线,那么zookeeper中的临时节点会因为会话关闭而被删除,基于watcher机制将通知中间件其他节点,时效性很高
- 持久顺序(PERSISTENT_SEQUENTIAL)节点 :除了具有持久(PERSISTENT)节点的特性之外, 子节点的名称还具有顺序性。比如 /node1/app0000000001 、/node1/app0000000002 。
- 临时顺序(EPHEMERAL_SEQUENTIAL)节点 :除了具备临时(EPHEMERAL)节点的特性之外,子节点的名称还具有顺序性。
- znode状态信息解释
| znode 状态信息 | 解释 |
|---|---|
| cZxid | create ZXID,即该数据节点被创建时的事务 id |
| ctime | create time,即该节点的创建时间 |
| mZxid | modified ZXID,即该节点最终一次更新时的事务 id |
| mtime | modified time,即该节点最后一次的更新时间 |
| pZxid | 该节点的子节点列表最后一次修改时的事务 id,只有子节点列表变更才会更新 pZxid,子节点内容变更不会更新 |
| cversion | 子节点版本号,当前节点的子节点每次变化时值增加 1 |
| dataVersion | 数据节点内容版本号,节点创建时为 0,每更新一次节点内容(不管内容有无变化)该版本号的值增加 1 |
| aclVersion | 节点的 ACL 版本号,表示该节点 ACL 信息变更次数 |
| ephemeralOwner | 创建该临时节点的会话的 sessionId;如果当前节点为持久节点,则 ephemeralOwner=0 |
| dataLength | 数据节点内容长度 |
| numChildren | 当前节点的子节点个数 |
zookeeper 写入过程
每次客户端对zookeeper进行更新时,会先写磁盘的事务日志,再把数据存入内存数据库中,后面定期会对内存数据库做一次快照存入磁盘
Watcher机制
**Watcher(事件监听器),是 ZooKeeper 中的一个很重要的特性。ZooKeeper 允许用户在指定节点上注册一些 Watcher,并且在一些特定事件触发的时候,ZooKeeper 服务端会将事件通知到感兴趣的客户端上去,该机制是 ZooKeeper 实现分布式协调服务的重要特性。**
ZooKeeper 集群
集群角色
ZooKeeper 中没有选择传统的 Master/Slave 概念,而是引入了 Leader、Follower 和 Observer 三种角色。如下图所示

- Leader:为客户端提供读和写的服务,负责投票的发起和决议,更新系统状态。
- Follow:为客户端提供读服务,如果是写服务则转发给 Leader。参与选举过程中的投票。
- Observer:为客户端提供读服务,如果是写服务则转发给 Leader。也不参与“过半写成功”策略。不参与选举过程中的投票。
服务器状态
- LOOKING :寻找 Leader。
- LEADING :Leader 状态,对应的节点为 Leader。
- FOLLOWING :Follower 状态,对应的节点为 Follower。
- OBSERVING :Observer 状态,对应节点为 Observer,该节点不参与 Leader 选举。
过半机制
ZooKeeper 集群在宕掉几个 ZooKeeper 服务器之后,如果剩下的 ZooKeeper 服务器个数大于宕掉的个数的话整个 ZooKeeper 才依然可用。
所以设置zookeeper集群机器数最好为奇数,因为2n 和 2n-1 的容忍度是一样的,都是 n-1。
比如假如我们有 3 台,那么最大允许宕掉 1 台 ZooKeeper 服务器,如果我们有 4 台的的时候也同样只允许宕掉 1 台。 假如我们有 5 台,那么最大允许宕掉 2 台 ZooKeeper 服务器,如果我们有 6 台的的时候也同样只允许宕掉 2 台。综上,何必增加那一个不必要的 ZooKeeper 呢?
过半机制还可以防止集群脑裂(既整个集群因为网络等原因分成了两个或多个小集群,而每个小集群都会选举出自己的leader,当整个集群回复通信的时候,就会出现多个leader的情况),而过半机制的存在,让整个集群哪怕出现故障也最多仅有一个小集群可以存活
Zookeeper命令
ls命令
查看目录下的节点信息
ls [-s] [-w] [-R] path
- -s:展示出节点的详细信息和状态信息
- -w:添加watch(监听子节点变化)
- -R:展示节点的级联(包括自己和子节点)
stat命令
查看目录下状态信息
stat [-w] path
- -w:添加watch
create命令
创建节点,默认持久节点
create [-s] [-e] [-c] [-t ttl] path [data] [acl]
- -s:有序节点
- -e:临时节点
- -t:带过期时间节点,比如:create ‐t 10 /ttl,需要在 zoo.cfg中添加 extendedTypesEnabled=true 开启,不能用于临时节点
set命令
修改节点内容
set [-s] [-v version] path data
- -s:更新节点并显示状态信息
- -v:指定数据版本号,如果指定版本号与当前版本号不一致,则更新失败,如set -v 1 /v “hello”
get命令
获取节点内容
get [-s] [-w] path
- -s:获取节点内容以及状态信息
- -w:添加一个watch(监听节点数据变化)
delete命令
删除节点
delete [-v version] path
- -v:指定数据版本号,如果指定版本号与当前版本号不一致,则删除失败,如delete -v 1 /v “hello”
deleteall命令
级联删除该节点和子节点
deleteall path [-b batch size]
addWatch命令
在 Zookeeper 3.6.0版本之后,客户端可以在节点上创建永久监听,永久监听在被触发后不会被删除。
addWatch [-m mode] path
- -m:指定模式
- PERSISTENT:该节点的数据变化以及子节点的变化会触发相应事件,子节点的数据变化不会触发。
- PERSISTENT_RECURSIVE:该节点的数据变化以及所有子孙节点的目录或者数据变化都会触发相应事件。
其他命令
- history:显示最近执行的11条命令的历史记录
- getAllChildrenNumber:获取节点下的所有子孙节点数量
- getEphemerals:获取当前客户端创建的所有临时节点
ACL
- scheme:代表采用某种权限机制
- id:代表允许访问的用户
- permissions:代表权限(组合字符串)
scheme:权限策略
- world : world下只有一个id,即只有一个用户,也就是anyone,那么组合的写法就是world:anyone:[permissions]。 world:anyone 代表任何人,zookeeper 中对所有人有权限的结点就是属于 world:anyone 的。
- auth:代表认证登录,需要注册用户有权限就可以,使用的是明文密码,形式为auth:user:password:[permissions]。
它不需要 id, 只要是通过 authentication 的 user 都有权限(zookeeper 支持通过 kerberos来进行 - authencation,也支持 username/password 形式的 authentication)。
- digest:需要对密码加密才能访问,使用的是加密密码,组合形式为digest: username:BASE64(SHA1(password)) :[permissions]。
- ip:它对应的 id 为客户机的 IP 地址,设置的时候可以设置一个 ip 段,此时限制ip进行访问。比如ip:192.168.1.1:[permissions]
- super:代表超级管理员,拥有所有的权限
id:用户
id 是验证模式,不同的 scheme,id 的值也不一样。默认为anyone。
- scheme 为 auth 时,id为:username:password
- scheme 为 digest 时,id为:username:BASE64(SHA1(password))
- scheme 为 ip 时,id为:客户端的 ip 地址。
- scheme 为 world 时,id为:anyone。
permission:权限
Zookeeper定义了五种权限:
- CREATE(c):创建子节点的权限。允许创建子节点;
- DELETE(d):删除节点的权限。允许删除子节点;
- READ(r):读取节点数据的权限。允许从节点获取数据并列出其子节点;
- WRITE(w):修改节点数据的权限。允许为节点设置数据;
- ADMIN(a):设置子节点权限的权限,允许为节点设置权限。
CREATE、READ、WRITE、DELETE、ADMIN 也就是增、删、改、查、管理权限,这 5 种权限简写为 crwda(即单词的首字符缩写)。
getAcl命令
查看指定节点 ACL信息
getAcl [-s] path
- -s:查看节点详细信息
setAcl命令
设置指定节点的ACL 信息
setAcl [-s] [-v version] [-R] path acl
addauth命令
addauth命令:添加认证用户
命令格式:addauth scheme auth
- scheme:(digest:是授权方式)格式为:digest username:password
- auth:就是分配权限, crwda。如果不写时表示创建用户,可以通过setAcl命令来设置权限
Zookeeper 集群搭建
配置
zoo.cfg需要加入以下配置
1 | #不同节点需要配置不同的端口,ip不同的话不用考虑端口 |