linux

ZooKeeper会话机制

小樊
50
2025-09-27 12:48:45
栏目: 大数据

ZooKeeper会话机制详解

一、会话的基本概念

会话(Session) 是ZooKeeper客户端与服务端之间的TCP长连接抽象,是维护客户端状态(如临时节点生命周期、Watcher通知、请求顺序性)的核心机制。会话通过**会话ID(sessionId)**唯一标识,由服务端在客户端连接时分配,确保分布式环境下会话的一致性。

二、会话的创建

客户端通过ZooKeeper.connect()方法发起连接时,需指定会话超时时间(sessionTimeout)(单位:毫秒)。服务端会将该值调整至2×tickTime20×tickTime之间(tickTime是ZooKeeper的基本时间单位,默认2000ms),并生成全局唯一的sessionId(算法:高8位为服务器ID,后56位为当前时间毫秒数左移8位)。创建完成后,客户端状态转为CONNECTED,服务端通过SessionTracker(会话管理器)记录会话信息。

三、会话的状态生命周期

会话状态随连接情况动态变化,主要包括:

状态转换逻辑:CONNECTINGCONNECTED→(断开)→RECONNECTINGCONNECTED(重连成功)或CLOSED(重连失败/超时)。

四、会话的管理:分桶策略与心跳机制

1. 分桶策略(Bucket Strategy)

服务端为提升会话超时检查效率,将所有会话按**过期时间(ExpirationTime)**分组到不同“桶”中。ExpirationTime计算公式为:
ExpirationTime = 当前时间 + sessionTimeout
服务端将ExpirationTime向上取整为tickTime的整数倍(如tickTime=2000mssessionTimeout=5000ms,则ExpirationTime=6000ms),并将会话放入对应桶中。检查时仅需遍历即将过期的桶,而非所有会话,大幅降低时间复杂度。

2. 心跳机制(Heartbeat)

心跳是维持会话活跃的关键。客户端通过两种方式发送心跳:

服务端收到心跳后,调用touchSession方法更新会话的ExpirationTime,并将会话从旧桶迁移至新桶(对应新的过期时间)。

五、会话的超时处理

若服务端在sessionTimeout时间内未收到客户端心跳,会判定会话过期,执行以下流程:

  1. 标记失效:将会话的isClosing属性设为true,停止处理该会话的新请求。
  2. 收集临时节点:从内存数据库中获取该会话创建的所有临时节点(ephemeralOwner不为0的节点)。
  3. 删除临时节点:将临时节点删除操作转换为事务变更,写入事务日志并同步至集群。
  4. 清理会话:从SessionTracker中移除会话记录,关闭对应的NIOServerCnxn连接。

此时,客户端若仍在尝试操作,会收到SessionExpired异常,需重新创建会话并恢复临时数据(如重新创建临时节点)。

六、会话的重新连接

客户端与服务端断开连接后,会自动启动重连机制(Reconnecting状态):

七、会话与临时节点、Watcher的关联

0
看了该问题的人还看了