ZooKeeper:07---基础语法(会话:session)
分类:
文章
•
2024-07-27 14:09:04
一、会话相关基础概念
-
在对ZooKeeper集合执⾏任何请求前,⼀个客户端必须先与服务建⽴会话。会话的概念⾮常重要,对ZooKeeper的运⾏也⾮常关键。客户端提交给ZooKeeper的所有操作均关联在⼀个会话上
- 当⼀个会话因某种原因⽽中⽌时,在这个会话期间创建的临时节点将会消失
sessionID
- 在为客户端创建会话之前,服务端首先会为每个客户端都分配一个sessionID
- 由于 sessionID是Zookeeper会话的一个重要标识,许多与会话相关的运行机制都是基于这个 sessionID 的,因此,无论是哪台服务器为客户端分配的 sessionID,都务必保证全局唯一
编程客户端session
- 当客户端通过某⼀个特定语⾔套件来创建⼀个ZooKeeper句柄时,它就会通过服务建⽴⼀个会话。客户端初始连接到集合中某⼀个服务器或⼀个独⽴的服务器
-
客户端通过TCP协议与服务器进⾏连接并通信,但当会话⽆法与当前连接的服务器继续通信时,会话就可能转移到另⼀个服务器上。ZooKeeper客户端库透明地转移⼀个会话到不同的服务器
二、会话配置参数
- Session的sessionTimeout值用来设置一个客户端会话的超时时间
- 当由于服务器压力太大、网络故障或是客户端主动断开连接等 各种原因导致客户端连接断开时,只要在sessionTimeout规定的时间内能够重新连接上集群中任意一台服务器,那么之前创建的会话仍然有效
minSessionTimeout
-
最⼩会话超时时间,单位为毫秒。当客户端建⽴⼀个连接后就会请求⼀个明确的超时值,⽽客户端实际获得的超时值不会低于 minSessionTimeout的值
- ZooKeeper开发⼈员很想⽴刻且准确地检测出客户端故障发⽣的情况, 遗憾的是,在前面一文的“通过ZooKeeper构建分布式系统”中(https://blog.****.net/qq_41453285/article/details/107073944)已经介绍过,系统不可能实时处理这种情况,⽽是通过⼼跳和超时来处理。超时取决于ZooKeeper客户端与服务器之间的响应能⼒,更重要的是两者之间的⽹络延时和可靠性。超时时间允许的最⼩值为客户端与服务器之间⽹络的环回时间,但偶尔还是可能发⽣丢包现象,当这种情况发⽣时,因为重传超时导致接收响应时间的增加,并会导致接收 重发包的延时。
-
minSessionTimeout的默认值为tickTime值的2倍。配置该参数值过低 可能会导致错误的客户端故障检测,配置该参数值过⾼会延迟客户端故障的检测时间
maxSessionTimeout
-
会话的最⼤超时时间值,单位为毫秒。当客户端建⽴⼀个连接后就会 请求⼀个明确的超时值,⽽客户端实际获得的超时值不会⾼于 maxSessionTimeout的值。
- 虽然该参数并不会影响系统的性能,但却可以限制⼀个客户端消耗系统资源的时间,默认情况下maxSessionTimeout的时间为tickTime的20倍
三、会话请求顺序
-
会话提供了顺序保障,这就意味着同⼀个会话中的请求会以FIFO(先 进先出)顺序执⾏。通常,⼀个客户端只打开⼀个会话,因此客户端请求将全部以FIFO顺序执⾏
多会话之间未必能遵循FIFO原则
- 如果客户端拥有多个并发的会话,FIFO顺序在多个会话之间未必能够保持。⽽即使⼀个客户端中连贯的会话并不重叠,也未必能够保证FIFO顺序
-
下⾯的情况说明如何发⽣这种问题:
- ①客户端建立了⼀个会话,并通过两个连续的异步调用来创建/tasks和/workers
- ②第⼀个会话过期
- ③客户端创建另⼀个会话,并通过异步调用创建/assign
- 在这个调⽤顺序中,可能只有/tasks和/assign成功创建了,因为第⼀个会话保持了FIFO顺序,但在跨会话时就违反了FIFO顺序
四、会话的状态
-
⼀个会话的主要可能的状态有:CONNECTING、 CONNECTED、CLOSED和NOT_CONNECTED
-
状态的转换依赖于发⽣在客户端与服务之间的各种事件(见下图):
- ⼀个会话从NOT_CONNECTED状态开始,当ZooKeeper客户端初始化后转换到CONNECTING状态(箭头①)
- 正常情况下,成功与 ZooKeeper服务器建⽴连接后,会话转换到CONNECTED状态(箭头②)
- 当客户端与ZooKeeper服务器断开连接或者⽆法收到服务器的响应时,它就会转换回CONNECTING状态(箭头③)并尝试发现其他ZooKeeper服务器:
- 如果可以发现另⼀个服务器或重连到原来的服务器,当服务器确认会话有效后,状态又会转换回CONNECTED状态(箭头②)
- 否则,它将会声明会话过期,然后转换到CLOSED状态(箭头④)
- 应⽤也可以显式地关闭会话(箭头④和箭头⑤)
注意:发⽣网络分区时等待CONNECTING
- 如果⼀个客户端与服务器因超时⽽断开连接,客户端仍然保持CONNECTING状态
- 如果因⽹络分区问题导致客户端与ZooKeeper集合被隔离⽽发⽣连接断开,那么其状态将会⼀直保持,直到显式地关闭这个会 话,或者分区问题修复后,客户端能够获悉ZooKeeper服务器发送的会话已经过期
- 发⽣这种⾏为是因为ZooKeeper集合对声明会话超时负责,⽽不是客户端负责。直到客户端获悉ZooKeeper会话过期,否则客户端不能声明自⼰的会话过期。然⽽,客户端可以选择关闭会话
五、客户端重连
客户端会尝试连接哪⼀个服务器?
- 在仲裁模式下,客户端有多个服务器可以连接,⽽在独立模式下,客户端只能尝试重新连接单个服务器
- 在仲裁模式中,应用需要传递可用的服务器列表给客户端,告知客户端可以连接的服务器信息并选择⼀个进⾏连接
重连规则
-
重连规则为:
- 当尝试连接到⼀个不同的服务器时,这个服务器的ZooKeeper状态要与最后连接的服务器的ZooKeeper状态保持最新
- 例如客户端不能连接到这样的服务器:比客户端更新还迟的服务器
-
ZooKeeper通过在服务中排序更新操作来决定状态是否最新。ZooKeeper确保每⼀个变化相对于所有其他已执⾏的更新是完全有序的。因此,如果⼀个客户端在位置i观察到⼀个更新,它就不能连接到只观察到i'<i的服务器上。在ZooKeeper实现中,系统根据每⼀个更新建⽴的顺序来分配给事务标识符
-
下图描述了在重连情况下事务标识符(zkid)的使⽤:
- 当客户端因超时与s1断开连接后,客户端开始尝试连接s2,但s2延迟于客户端所知的变化
- 然⽽,s3对这个变化的情况与客户端保持⼀致,所以s3可以安全连接