【Zookeeper】01_系统模型


Zookeeper模型分成数据模型,节点特性,版本,Watcher,ACL五个部分。

1 数据模型

  • 树形结构:每个节点成为ZNode,是数据的最小单元,每个节点可以存放数据或者是子节点。
  • 事务ID:ZXID,每次对服务器状态进行操作(节点创建与删除;节点内容更新;客户端会话与失效),就会分配全局的事务ID

2 节点类型

根据节点生命周期长短分成持久节点,临时节点,顺序节点

  • 持久节点:一直存在服务端,直到手动删除。
  • 临时节点:生命周期是客户端的会话失效周期,不是TCP断开连接。临时节点只能作为叶子节点,不能基于临时节点创建子节点。
  • 顺序节点:节点可能还表现为顺序特性,即节点在父节点列表中是否标记创建顺序。

3 状态信息

节点信息包含节点数据内容以及状态信息。

  • czxid:reated ZXID,表示该节点被创建时的事务ID
  • mzxid:Modified ZXID,表示该节点最后一次被更新时的事务ID
  • ctime:表示节点被创建的时间
  • mtime:表示该节点最后一次被更新时的时间
  • version:数据节点的版本号。节点被创建后,被更新过的次数,即使更新的内容与原内容相同,也视为一次更新
  • cversion:子节点的版本号
  • aversion:节点的ACL版本号
  • ephemeralOwner:创建该临时节点的会话的SessionID。如果该节点为持久节点,那么这个属性值为0
  • dataLength:数据内容的长度
  • numChildren:当前节点的子节点个数
  • pzxid:表示该节点的子节点列表最后一次被修改时的事务ID。只有子节点列表变更了才会变更pzxid,子节点内容变更不会影响pzxid

4 Watcher机制

一对多的发布订阅模式,客户端向服务端注册watcher,监听某一特定主题的对象,当主题对象自身发生变化时,会通知所有的订阅者。

4.1 Watcher基础

Watcher机制的对象包括:

  • 客户端线程
  • 客户端WatcherManager
  • 服务端

Watcher机制:

  1. 客户端向服务端注册watcher同时会把watcher对象存入客户端WatcherManager中
  2. 当服务端触发Watcher事件后,服务端会向客户端发送通知
  3. 客户端线程从WatcherManager中取出对应的Watcher对象,执行回调逻辑。

Watcher特性包含:

  • 注册一次性。watcher一旦被触发,就会被删除。如果需要监听,就要手动注册。否则一些更新比较频繁的节点,每次变动都要不断地将通知反馈给客户端,对与网络以及服务端性能影响很大。
  • 客户端Watcher回调是串行同步的,保证了每个wathcer的顺序。
  • 轻量级watcher。WatchedEvent是Watcher机制的最小通知单元,只包含了通知状态,事件类型,节点路径,不给出具体的变化内容,需要客户端自己去相应节点获取变化的内容,保证了客户端服务端交互的数据量级。

4.2 Watcher事件

Watcher通知状态与事件类型
在这里插入图片描述
注意:

  • NodeDataChanged:与dataVersion一致,即使变更内容前后一样,也会触发此事件。
  • NodeChildrenChanged:所关注的节点的子节点列表有变化。这里说的变化是指子节点的个数和组成,具体到子节点内容的变化是不会通知的。

4.3 process回调方法

WatchedEvent包含三个属性:事件状态keeperstate,事件类型EventType,节点路径path。

abstract public void process(WatchedEvent event);

在这里插入图片描述
在这里插入图片描述

WatcherEvent与WatchedEvent:

  • WatchedEvent表示服务端与客户端之间的逻辑对象
  • WatcherEvent实现了序列化接口,可用于网络传输
  • 服务端生成WatchedEvent后调用getWrapper方法包装成可序列化的WatcherEvent事件,以便传输到客户端;客户端接到后将WatcherEvent转换成WatchedEvent,使用process进行处理

4.4 Watcher工作机制

watcher注册机制包括:

  • 客户端注册Watcher
  • 服务端处理Watcher
  • 客户端回调Watcher

4.4.1 客户端注册Watcher

在这里插入图片描述
在这里插入图片描述

/**
 */
public interface ClientWatchManager {
    /**
     * Return a set of watchers that should be notified of the event. The 
     * manager must not notify the watcher(s), however it will update it's 
     * internal structure as if the watches had triggered. The intent being 
     * that the callee is now responsible for notifying the watchers of the 
     * event, possibly at some later time.
     * 
     * @param state event state
     * @param type event type
     * @param path event path
     * @return may be empty set but must not be null
     */
    public Set<Watcher> materialize(Watcher.Event.KeeperState state,
        Watcher.Event.EventType type, String path);
}

关键类

  • ZooKeeper:客户端基础类、存储了ClientCnxn和ZkWatcherManager
  • ZKWatchManager:ZooKeeper的内部类,实现了ClientWatchManager接口,主要用来存储各种类型的Watcher,主要有三种:dataWatches、existWatches、childWatches以及一个默认的defaultWatcher。
  • ClientCnxn:与服务端的交互类,主要包含以下对象:outgoingQueue、SendThread和EventThread。
    1. 其中outgoingQueue未待发送给服务端的Packet列表,
    2. SendThread线程负责和服务端进行请求交互
    3. EventThread线程则负责客户端Watcher事件的回调执行
  • WatchRegistration:Zookeeper的内容类,包装了Watcher和clientPath,并且负责Watcher的注册
  • Packet:ClientCnxn的内部类,与Zookeeper服务端通信的交互类

客户端处理步骤:

  1. 创建zk客户端对象实例时注册watcher,这个 Watcher 将作为整个 ZooKeeper 会话期间的默认 Watcher,它会一直被保存在客户端 ZKWatchManagerdefaultWatcher 里面。(getData, getChildren, exists方法中也可以注册watcher)
  2. 例如getData注册Watcher后,客户端会向当前的request标记,设置为“使用watcher监听”,同时封装WatcherRegistration对象用于暂时保存数据节点路径和wathcer对应关系。
  3. WatchRegistration被封装成Packet对象,放入发送队列等待客户端发送。客户端没有把Watcher对象发送给服务端,只是将request与requestHeader两个属性序列化传输,否则服务端就容易出现内存紧张甚至溢出的危险。
  4. ZKWatcherManager.dataWatches是Map<String, Set>保存数据节点路径与Watcher对象关系。

4.4.2 服务端处理Watcher

对于注册 Watcher 请求,FinalRequestProcessor 的 ProcessRequest 方法会判断当前请求是否需要注册 Watcher,如果为 true,就会将当前的 ServerCnxn 对象和数据节点路径传入 getData 方法中去。ServerCnxn 是一个 ZooKeeper 客户端和服务器之间的连接接口,代表了一个客户端和服务器的连接,我们后面讲到的 process 回调方法,实际上也是从这里回调的,所以可以把 ServerCnxn 看作是一个 Watcher 对象。数据节点的节点路径和 ServerCnxn 最终会被存储在 WatchManager 的 watchTable 和 watch2Paths 中。
WatchManager 负责 Watcher 事件的触发,它是一个统称,在服务端 DataTree 会托管两个 WatchManager,分别是watchTable和 watch2Paths,分别对应数据变更 Watcher 和节点变更 Watcher。

当DataTree中节点数据内容或版本发生变化或节点变更时,会调用相应方法去触发 WatchManager 的 triggerWatch 方法,该方法返回 ZNODE 的信息,自此进入到回调本地 process 的序列。

4.4.3 客户端回调Watcher

SendThread的response()方法负责接收这个客户端事件通知。首先会对replyHeader中xid进行判断,如果是-1,则说明是一个通知类型的响应。作以下处理:

  1. 反序列化:ZooKeeper客户端接到请求后,首先将字节流转换成WatcherEvent对象。
  2. 处理chrootPath:如果客户端设置了chrootPath属性,那么需要对服务端传过来的完整的节点路径进行chrootPath处理,生成客户端的一个相对节点路径。
  3. 还原WatchedEvent:将WatcherEvent对象转换成WatchedEvent。
  4. 回调Watcher:将WatchedEvent对象交给EventThread线程,在下一个轮询周期中进行Watcher回调。

5 ACL保障数据安全

用于对节点的权限进行控制,一个有效的ACL信息包含:权限模式(Scheme),授权对象(ID),权限(Permission),即"scheme:ID:permission"。

参考

  • https://www.cnblogs.com/shamo89/p/9787176.html
  • 图比较详细,https://www.cnblogs.com/ZhuChangwu/p/11593642.html
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值