ZooKeeper重要概念解读
Data model(数据模型)
ZooKeeper数据模型采用层次化的多叉树型结构,每个节点上都可以存储数据,这些数据可以是数字,字符串或者是二进制序列。并且,每个节点还可以拥有N个子节点,最上层是根节点以“/”来代表。每个数字节点在ZooKeeper中被成为znode,他是ZooKeeper中数据的最小单位。并且,每个znode都一个唯一的路径标识。
强调一句:ZooKeeper主要是用来协调服务的,而不是用来存储业务数据的,所以不要放比较大的数据在znode上,ZooKeeper给出的上线是每个节点的数据大小最大是1M。
从下图可以更直观地看出:ZooKeeper节点路径标识方式和Unix文件系统路径非常相似,都是由一系列使用斜杠“/”进行分割的路径表示,开发人员可以向这个节点中写入数据,也可以在节点下面创建子节点。
znode(数据节点)
介绍了ZooKeeper树形数据模型之后,我们知道每个数据节点在ZooKeeper中被称为znode,它是ZooKeeper中数据的最小单位。你要存放的数据就放在上面,是你使用ZooKeeper过程中经常需要接触到的一个概念。
znode 4种类型
我们通过是将znode分为4大类:
- 持久 (PERSISTENT)节点:一旦创建就一直存在即使ZooKeeper集群宕机,直到将其删除。
- 临时 (EPHEMERAL)节点:临时节点的生命周期是与客户端会话(session)绑定的,会话消失则节点消失。并且,临时节点只能做叶子节点,不能创建子节点。
- 持久顺序 (PERSISTENT_SEQUENTIAL)节点:除了具有持久节点的特性之外,子节点的名称还具有顺序性。比如 /node1/app01, /node1/app02。
- 临时顺序 (PERSISTENT_SEQUENTIAL)节点:除了具有临时节点的特性之外,子节点的名称还具有顺序性。
znode数据结构
每个znode由2部分组成
- stat:状态信息
- data:节点存放的数据具体内容
如下所示,通过get命令来获取根目录下的dubbo节点内容。
[zk: 127.0.0.1:2181(CONNECTED) 6] get /dubbo
# 该数据节点关联的数据内容为空
null
# 下面是该数据节点的一些状态信息,其实就是 Stat 对象的格式化输出
cZxid = 0x2
ctime = Tue Nov 27 11:05:34 CST 2018
mZxid = 0x2
mtime = Tue Nov 27 11:05:34 CST 2018
pZxid = 0x3
cversion = 1
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 0
numChildren = 1
Stat类中包含一个数据节点的所有状态信息的字段,包括事务ID-cZxid、节点创建时间-ctime和子节点个数-numChildren等等。
看下每个znode状态信息代表什么:
znode状态信息 |
解释 |
cZxid |
create ZXID,即该数据节点被创建时的事务id |
ctime |
create time,即该节点的创建时间 |
mZxid |
modified ZXID,即该节点最终一次更新时的事务id |
mtime |
modified time,即该节点最后一次更新时间 |
pZxid |
该节点的子节点列表最后一次修改的事务id,只有子节点列表变更才会更新pZid,子节点内容变更不会更新 |
cversion |
子节点版本号,当前节点的子节点每次变化时值增加1 |
dataVersion |
数据节点内容版本号,节点创建时为0,每更新一次节点内容(不管内容有无变化)该版本号的值增加1 |
aclVersion |
节点的ACL版本号,表示该节点ACL信息变更次数 |
ephemeralOwner |
创建该临时节点的会话的sessionId;如果当前节点为持久节点,则ephemeralOwner=0 |
dataLength |
数据节点内容长度 |
numChildren |
当前节点的子节点个数 |
版本version
对应于每个znode,ZooKeeper都会为其维护一个叫做Stat的数据结构,Stat中记录这个znode的三个相关版本:
- dataVersion当前znode节点版本号
- cversion:当前znode子节点版本
- aclVersion:当前znode的ACL版本
ACL(权限控制)
ZooKeeper采用ACL(AccessControlLists)策略来进行权限控制,类似与UNIX文件系统的权限控制。
对于znode操作权限,ZooKeeper提供了一下5种:
- CREATE:能创建子节点
- READ:能获取节点数据和列出其子节点
- WRITE:能设置/更新节点数据
- DELETE:能删除子节点
- ADMIN:能设置节点ACL权限
其中尤其需要注意的是,CREATE和DELETE这两种权限都是针对子节点的权限控制。
对于身份认证,提供了以下几种方式:
- world:默认方式,所有用户都可无条件访问
- auth:不使用任何id,代表任何已认证的用户
- digest:用户名:密码认证方式:username:password
- ip:对指定ip进行限制。
Watcher(事件监听器)
Watcher(事件监听器),是ZooKeeper中一个很重要的特性。ZooKeeper允许用户在指定节点上注册一些Watcher,并且在一些特定事件出发的时候,ZooKeeper服务端会将事件通知到感兴趣的客户端上去,该机制是ZooKeeper实现分布式协调服务的重要特性。
会话(session)
Session可以看作是ZooKeeper服务器与客户端之间的一个TCP长连接,通过这个连接,客户端能够通过心跳检测与服务器保持有效的会话,也能够向ZooKeeper服务器发送请求并接受响应,同时还能够通过该连接接受来自服务器的Watcher事件通知。
Session有一个属性叫做:SessionTimeOut,SessionTimeOut代表会话的超时时间。当由于服务器压力太大、网络故障或是客户端主动断开连接等各种原因导致客户端连接断开时,只要在SessionTimeOut规定事件内能够重新连接上集群中任意一台服务器,那么之前创建的会话任然有效。
另外,在为客户端创建会话之前,服务端首先会为每个客户端都分配一个SessionID。由于SessionID是Zookeeper会话的一个重要标识,许多与会话相关的运行机制都是基于这个SessionID的,因此,无论是哪台服务器为客户端分配的SessionID,都务必保证全局唯一。