参考博客:https://www.cnblogs.com/leesf456/p/6072597.html
1. 数据模型
-
树
Zookeeper的数据节点称为ZNode,ZNode是Zookeeper中数据的最小单元,每个ZNode都可以保存数据,同时还可以挂载子节点,因此构成了一个层次化的命名空间,称为树
。

-
事务ID
在Zookeeper中,事务是指能够改变Zookeeper服务器状态的操作,一般包括节点创建与删除,数据节点内容更新和客户端会话创建与失效
,对于每个事务请求,Zookeeper都会为其分配一个全局唯一的事务ID,用ZXID表示,通常是64位的数字,每个ZXID对应一次更新操作
,从这些ZXID中可以间接地识别出Zookeeper处理这些更新操作请求的全局顺序。
2. 节点特性
-
节点类型
在Zookeeper中,每个数据节点都是由生命周期的,类型不同则会不同的生命周期,节点类型可以分为持久节点(PERSISTENT)、临时节点(EPHEMERAL)、顺序节点(SEQUENTIAL)三大类,可以通过组合生成如下四种类型节点
持久节点(PERSISTENT)。节点创建后便一直存在于Zookeeper服务器上,直到有删除操作来主动清楚该节点。
持久顺序节点(PERSISTENT_SEQUENTIAL)。相比持久节点,其新增了顺序特性,每个父节点都会为它的第一级子节点维护一份顺序,用于记录每个子节点创建的先后顺序。在创建节点时,会自动添加一个数字后缀,作为新的节点名,该数字后缀的上限是整形的最大值。
临时节点(EPEMERAL)。临时节点的生命周期与客户端会话绑定,客户端失效,节点会被自动清理。同时,Zookeeper规定不能基于临时节点来创建子节点,即临时节点只能作为叶子节点。
临时顺序节点(EPEMERAL_SEQUENTIAL)。在临时节点的基础添加了顺序特性。
-
状态信息
每个节点除了存储数据外,还存储了节点本身的一些状态信息,可通过get命令获取。
比如启动客户端,输入get /zookeeper来获取/zookeeper节点的stat信息
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
stat对象的属性说明
状态属性 | 说明 |
---|---|
cZxid | 数据节点创建时的事务ID |
ctime | 数据节点创建时的时间 |
mZxid | 数据节点最后一次更新时的事务ID |
mtime | 数据节点最后一次更新时的时间 |
pZxid | 数据节点的子节点列表最后一次被修改(是子节点列表变更,增加或者删除,而不是子节点内容变更)时的事务ID |
cversion | 子节点的版本号 |
dataVersion | 数据节点的版本号 |
aclVersion | 数据节点的ACL版本号 |
ephemeralOwner | 如果节点是临时节点,则表示创建该节点的会话的SessionID;如果节点是持久节点,则该属性值为0 |
dataLength | 数据内容的长度 |
numChildren | 数据节点当前的子节点个数 |
3 版本--保证分布式数据原子性操作
每个数据节点都具有三种类型的版本信息,对数据节点的任何更新操作都会引起版本号的变化。
version-- 当前数据节点数据内容的版本号
cversion-- 当前数据子节点的版本号
aversion-- 当前数据节点ACL变更版本号
上述各版本号都是表示修改次数,如version为1表示对数据节点的内容变更了一次。即使前后两次变更并没有改变数据内容,version的值仍然会改变。version可以用于写入验证,类似于CAS。
4 Watcher--数据变更通知
Zookeeper使用Watcher机制实现分布式数据的发布/订阅功能。

Zookeeper的Watcher机制主要包括客户端线程、客户端WatcherManager、Zookeeper服务器三部分。客户端在向Zookeeper服务器注册的同时,会将Watcher对象存储在客户端的WatcherManager当中。当Zookeeper服务器触发Watcher事件后,会向客户端发送通知,客户端线程从WatcherManager中取出对应的Watcher对象来执行回调逻辑。
-
watch的接口
在zookeeper中,接口类watcher 用于表示一个标准的事件处理器,其定义了事件通知相关的逻辑,包含keeperstate 和EventType 两个枚举类,分别代表了通知状态和事件类型,同时定义了事件的回调方法:
abstract public void process(WatchedEvent event);
-
watch事件
同一个事件类型在不同的通知状态中的代表的含义有所不同,下面列举了常见的通知状态和事件类型
KeeperState | EventType | 触发条件 | 说明 |
---|---|---|---|
SyncConnected (3) | None (-1) | 客户端与服务端成功建立回话 | 此时客户端和服务处于连接状态 |
NodeCreated (1) | watcher 监听的对应数据节点被创建 | ||
NodeDeleted (2) | watcher 监听的对应数据节点被删除 | ||
NodeDataChanged (3) | watcher 监听的对应数据节点的数据内容发生变更 | ||
NodeChildrenChanged (4) | watcher 监听的对应数据节点的子节点列表发生变更 | ||
Disconnected (0) | None (-1) | 客户端与服务端断开连接 | 此时服务端与客户端处于断开连接状态 |
Expired (-112) | None (-1) | 回话超时 | 此时客户端回话失效,通常同时也会收到SessionException异常 |
AuthFailed (4) | None (-1) | 通常有两种情况:使用错误的scheme进行权限检查和sasl权限检查失败 | 通常会收到AuthFailedException异常 |
Unknown (-1) | None (-1) | 从3.1.0版本开始废弃 | |
NoSyncConnected (1) | None (-1) | 从3.1.0版本开始废弃 |
5.ACL--保障数据的安全
Zookeeper内部存储了分布式系统运行时状态的元数据,这些元数据会直接影响基于Zookeeper进行构造的分布式系统的运行状态,如何保障系统中数据的安全,从而避免因误操作而带来的数据随意变更而导致的数据库异常十分重要,Zookeeper提供了一套完善的ACL权限控制机制来保障数据的安全。
我们可以从三个方面来理解ACL机制:权限模式(Scheme)、授权对象(ID)、权限(Permission),通常使用scheme:id:permission
来标识一个有效的ACL信息。
-
权限模式:scheme
用来确定权限验证过程中使用的检验策略,有如下四种模式:
IP,通过IP地址粒度来进行权限控制,如"ip:192.168.0.110"表示权限控制针对该IP地址,同时IP模式可以支持按照网段方式进行配置,如"ip:192.168.0.1/24"表示针对192.168.0.*这个网段进行权限控制。
Digest,使用"username:password"形式的权限标识来进行权限配置,便于区分不同应用来进行权限控制。Zookeeper会对其进行SHA-1加密和BASE64编码
。
World,最为开放的权限控制模式,数据节点的访问权限对所有用户开放。
Super,超级用户,是一种特殊的Digest模式,超级用户可以对任意Zookeeper上的数据节点进行任何操作。
-
授权对象:ID
授权对象指的是指权限赋予的用户或一个指定实体,如IP地址或机器等。不同的权限模式通常有不同的授权对象。 -
权限:permission
权限是指通过权限检查可以被允许执行的操作,Zookeeper对所有数据的操作权限分为
CREATE(C: 节点创建权限)、
DELETE(D: 节点删除权限)、
READ(R:节点读取权限)、
WRITE(W:节点更新权限)、
ADMIN(A: 节点管理权限)。
下面举个例子来演示设置ACL,一般有两种方式设置acl
- 第一种在创建数据节点同时进行设置ACl权限的设置
create [-e] [-s] path data acl
比如:
create -e /zk-book init digest: foo:kWN6aNSbjcKWPqjiV7cg0N24raU=:cdrwa
- 第二种方式使用ACl命令对已经存在数据节点进行ACL进行设置
setAcl path acl
比如:
create -e /zk-book init
setAcl /zk-book digest: foo:kWN6aNSbjcKWPqjiV7cg0N24raU=:cdrwa
其中kWN6aNSbjcKWPqjiV7cg0N24raU是对原始密码进行SHA-1算法加密和BASE64编码,可以具体的DigestAuthenticationProvider来生成出来,具体如下
//对“username:password”进行编码
public class DigestAuthenticationProviderUsage {
public static void main( String[] args ) throws NoSuchAlgorithmException {
System.out.println( DigestAuthenticationProvider.generateDigest( "foo:zk-book" ) );
}
}
网友评论