第四章 Zookeeper技术内幕

4.1 重要理论

4.1.1 数据模型 znode

  zk数据存储结构是一个树形结构,根节点下挂载子节点,每个节点都是一个znode,是zk中数据的最小单元,每个znode都可以保存数据

  1. 节点类型

  持久节点:节点被创建后一直保存,直到删除

  持久顺序节点:父节点为儿子节点记录创建的顺序,即创建时在节点名字后添加数字,一共10位10进制数,从0开始计数

  临时节点:临时节点的生命周期和客户端的会话绑定在一起,会话消失则被清理。临时节点只能做叶子节点

  临时顺序节点:顺序含义同持久顺序节点

4.1.2 会话

  客户端和服务器建立TCP连接,一旦建立完成,客户端会话开始它的的生命周期

  1. 会话的状态

  CONNECTING:连接中,创建一个zk对象,代表将要连接的Server

  CONNECTED:已连接,将连接上的Server信息写到zk对象中

  CLOSED:已关闭,删除zk对象

  选择Server的源码分析,zk客户端初始化,对zk集群所有节点进行Collections.shuffle,然后轮询取出一个可以用的节点,根据节点的域名找到下面所有ip,对所有ip再次进行Collections.shuffle,取出第一个ip,进行连接

  2. 会话连接超时管理——客户端维护

  会话超时:连接超时、读超时

  3. 会话连接事件

  客户端和服务端长连接失效后,客户端进行重试,在重试过程中产生三种会话连接事件。每次建立连接,服务端会生成一个sessionId,同时服务端也会检测客户端连接状态,如果客户端连接超时,会删除sessionId

  • 连接丢失
  • 会话转移:sessionId未删除,客户端重新连接上其他节点,对服务端无感,客户端更新自己zk对象的ip地址和端口
  • 会话失效:sessionId已删除,客户端重新连接上其他节点,服务端告知客户端连接已失效,让客户端关闭连接重新建立连接

  4 会话空闲超时管理——服务端维护

  服务端记录客户端每次心跳时间,如果时间超时,将删除sessionId。服务端采用分桶策略进行超时管理,并不是精确的超时管理

  分桶策略

  将超时时间相近的会话,放到一个同一个桶里,每个桶有上下时间边界。当当前时间超过桶下界,整个桶中的sessionId将被清除

  客户端A建立连接,服务端会计算超时时间,这个超时时间将会落在某一个桶中,服务器会将sessionId放入对应的桶。

  超时判定:只要客户端A下次请求的时间,在桶的下界之前,则不算超时。

  重新分桶:客户端A下次请求的超时时间如果落在的下一个桶中,则将sessionId移动到对应的桶

  源码

   HashMap<Long,SessionSet> sessionSets;  会话桶集合,key是桶标识(桶下界时间),value是会话桶。

//会话桶类
Static class SessionSet{
    HashSet<SessionImpl> sessions = new HashSet<SessionImpl>();  
}

 

  SessionTrackerImpl#touchSession,将对应的sesssionId放到桶中,并判断当前会话是否关闭或不存在。注意SessionTrackerImpl是一个线程

  处理客户端连接请求:ZooKeeperServer#processConnectRequest,客户端第一次连接服务器,或者连接丢失,这两种情况下会发送连接请求

  处理客户端的数据包:ZooKeeperServer#processPacket,譬如发送心跳等等

  SessionTrackerImpl#run,一个无限循环,检查当前时间,是否已经到桶下界,如果没有,会在剩余时间中等待。如果时间到,则从会话桶集合中将该桶移除,并且遍历桶中所有会话,修改会话状态为关闭,并关闭会话。紧接着,获取下一个桶标识(当前桶标识+桶间距),继续循环。

4.1.4 Watcher机制

  zk通过Watcher机制实现发布/订阅模式

  1. 原理

  

  2. watcher事件

  比较重要的两个事件:

  NodeDataChanged,watcher监听对应数据节点的数据内容发生变化

  NodeChildrenChanged,watcher监听的节点的子节点列表发生变化

  3. watcher特性

  一次性:watcher触发后,zk将其从客户端的watcherManager中删除,服务器端也会删除该watcher。所以watcher机制不适合监听经常变化的场景。譬如Kafka将offset的管理放到了自身

  串行:一个watcher事件完全处理完(回调并删除),才能开始注册新的watcher

  轻量级:传递给服务端的是简易版watcher,回调逻辑放在客户端,不在服务器

4.2 客户端

  1. ZKClient

  2. Curator

 

posted @ 2021-05-24 10:53  walker993  阅读(22)  评论(0编辑  收藏  举报