临时节点删除引起的对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的维护尤其重要。

相关推荐
程序员岳焱6 小时前
Java 与 MySQL 性能优化:Java 实现百万数据分批次插入的最佳实践
后端·mysql·性能优化
麦兜*6 小时前
Spring Boot启动优化7板斧(延迟初始化、组件扫描精准打击、JVM参数调优):砍掉70%启动时间的魔鬼实践
java·jvm·spring boot·后端·spring·spring cloud·系统架构
大只鹅6 小时前
解决 Spring Boot 对 Elasticsearch 字段没有小驼峰映射的问题
spring boot·后端·elasticsearch
ai小鬼头6 小时前
AIStarter如何快速部署Stable Diffusion?**新手也能轻松上手的AI绘图
前端·后端·github
IT_10247 小时前
Spring Boot项目开发实战销售管理系统——数据库设计!
java·开发语言·数据库·spring boot·后端·oracle
bobz9657 小时前
动态规划
后端
stark张宇8 小时前
VMware 虚拟机装 Linux Centos 7.9 保姆级教程(附资源包)
linux·后端
亚力山大抵8 小时前
实验六-使用PyMySQL数据存储的Flask登录系统-实验七-集成Flask-SocketIO的实时通信系统
后端·python·flask
超级小忍9 小时前
Spring Boot 中常用的工具类库及其使用示例(完整版)
spring boot·后端
CHENWENFEIc9 小时前
SpringBoot论坛系统安全测试实战报告
spring boot·后端·程序人生·spring·系统安全·安全测试