临时节点删除引起的对Session id的思考<Zookeeper>

问题是如何发生的

在业务场景中,可能会有这样一种情况:数据为了交互方便,把实时性高的数据放在zk节点中,系统对zk节点进行监听,以达到一个实时拉取的效果。

假设有一个节点A,对应的Session我们命名为Session-a ,在t时刻,由于网络扰动A节点掉线了,那么就会触发Zookeeper的超时重试机制,但是注意:这个时候A节点还没有被删除。

然后在t+timeout时刻,某主机要拿A节点的数据,但是这个节点不在线,但是A节点还没有被删除,被认为是Disconnect,就会重新创建一个临时节点tmp去更新数据,他们的id是一样的。

然后session-a 的时间超了,到达了过期时间,Zookeeper就把这个A节点删除了,终止会话,就会触发到监听器把节点移除了,然后数据就丢了。

Curator的监听模式

Cache事件监听可以理解为一个本地缓存视图与远程Zookeeper视图的对比过程。Cache提供了反复注册的功能。Cache是一种缓存机制,可以借助Cache实现监听。简单来说,Cache在客户端缓存了znode的各种状态,当感知到zk集群的znode状态变化,会触发event事件,注册的监听器会处理这些事件。

Curator 事件有两种监听模式:

  • 标准的观察模式:使用Watcher 监听器(此法无法重复使用)
  • 缓存监听模式引入了一种本地缓存视图的Cache机制,来实现对Zookeeper服务端事件监听。

上述的问题是发生在Cache中的,Cache可以对znode的状态进行监听。

Session的创建

Session就是会话,当连接zk的时候,就会创建。Session中有两个关键性参数:

SessionId的生成基准很简单:一个是时间戳,一个是机器id

前面提到的节点删除时机就和时间强相关。 Session带有以下几个参数

  • SessionID:会话的唯一标识,由ZK来分配,如前面的Session-a
  • TimeOut:会话超时时间。在客户端与服务端连接的期间,如果因为某些原因断开了连接(如网络中断等等),该次会话以及其相关的临时节点不会被马上删除,而是等待TimeOut时间后,如果还没有重连上来,那么才会算节点真的失效了,相关的一些临时节点也会被删除
  • Expiration Time:TimeOut是一个相对时间,而Expiration Time则是在时间轴上的一个绝对过期时间。当发生前面的timeout耗尽还没有重连的时候,服务器会告诉客户端该会话已经失效(SESSION_EXPIRED) ExpirationTime=CurrentTime(当前时间)+TimeOut(超时时间)

SessionID和临时节点

在ZooKeeper中,临时节点和Session ID是相关联的,但并不是一对一的关系。 当客户端与ZooKeeper建立会话时,会生成一个唯一的Session ID,这个不难想到。那么什么是临时节点呢?

临时节点是相对持久节点的,持久节点是尝试在 ZooKeeper 中保持存在的节点,即使连接和Session中断也是如此。那么临时节点就是随着Session的消失而消失

因此,在同一个Session有效期间创建的所有临时节点都与它的Session ID相关联。

不难想到,一个Session可以同时创建多个临时节点,并且多个Session也可以共享相同的Session ID 例如,当客户端重新连接到的时候,所以临时节点可以帮助数据监听,尤其实在分布式环境中。

分桶机制-Expiration Time

Session是怎么样被管理的呢?那就是分桶机制。ZK会维护着一个个"桶",然后根据ExpirationTime把Session们分配到一个个的桶里面,ZK在进行扫描的时候,只需要扫描一个桶即可。

什么是ExpirationTime呢?

ExpirationInterval是ZK服务端定时检查过期Session的频率,默认为2000 ms,ExpirationTime是ExpirationInterval的倍数,是zk为了解决时间片太多不好落桶取的近似值。,而且在这种模式下,检查时间和每个Session的过期时间都可以在同一个时间节点上。这里我联想的是一致性hash的就近原则。

到此,我们从临时节点删除可以得到到各个时间点的关,尤其是在分布式场景中,为了效率我们常常使用临时节点,但是对Session的维护尤其重要。

相关推荐
王的宝库4 分钟前
Go 项目结构:从单文件到标准工程布局
开发语言·后端·golang
码事漫谈1 小时前
类型即世界:一个 C++ 程序员的本体论入门
后端
Rain的Java大神之路1 小时前
JavaWeb开发如何解决跨域问题
java·前端·后端·nginx·web安全·面试·运维开发
IT_陈寒4 小时前
Python的多线程居然是个假把式?搞清GIL让我少熬三天夜
前端·人工智能·后端
明月_清风4 小时前
位图与布隆过滤器:海量数据下的"存在性判断"艺术
前端·后端·算法
明月_清风4 小时前
Hash 表从入门到精通:Go 实战与工程细节
前端·后端·算法
考虑考虑4 小时前
ElasticSearch索引命令
运维·后端·elasticsearch
玉宇夕落5 小时前
背单词项目一:融会贯通:从零构建"单词大师"后台——Next.js + Supabase + Drizzle 全栈开发实战
后端
橙序员小站5 小时前
从 Demo 到生产:Agent Harness 如何把 AI 真正“接”进项目
后端·aigc·ai编程
她的男孩6 小时前
一个开源低代码框架的协作 SPI 是怎么设计的 ForgeAdmin 拆解 + 实战接入新平台
后端·算法·架构