ZooKeeper:07---基础语法(会话:session)

一、会话相关基础概念

  • 在对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状态(箭头④)
    • 应⽤也可以显式地关闭会话(箭头④和箭头⑤)

ZooKeeper:07---基础语法(会话:session)

注意:发⽣网络分区时等待CONNECTING

  • 如果⼀个客户端与服务器因超时⽽断开连接,客户端仍然保持CONNECTING状态
  • 如果因⽹络分区问题导致客户端与ZooKeeper集合被隔离⽽发⽣连接断开,那么其状态将会⼀直保持,直到显式地关闭这个会 话,或者分区问题修复后,客户端能够获悉ZooKeeper服务器发送的会话已经过期
  • 发⽣这种⾏为是因为ZooKeeper集合对声明会话超时负责,⽽不是客户端负责。直到客户端获悉ZooKeeper会话过期,否则客户端不能声明自⼰的会话过期。然⽽,客户端可以选择关闭会话

五、客户端重连

客户端会尝试连接哪⼀个服务器?

  • 在仲裁模式下,客户端有多个服务器可以连接,⽽在独立模式下,客户端只能尝试重新连接单个服务器
  • 在仲裁模式中,应用需要传递可用的服务器列表给客户端,告知客户端可以连接的服务器信息并选择⼀个进⾏连接

重连规则

  • 重连规则为:
    • 当尝试连接到⼀个不同的服务器时,这个服务器的ZooKeeper状态要与最后连接的服务器的ZooKeeper状态保持最新
    • 例如客户端不能连接到这样的服务器:比客户端更新还迟的服务器
  • ZooKeeper通过在服务中排序更新操作来决定状态是否最新。ZooKeeper确保每⼀个变化相对于所有其他已执⾏的更新是完全有序的。因此,如果⼀个客户端在位置i观察到⼀个更新,它就不能连接到只观察到i'<i的服务器上。在ZooKeeper实现中,系统根据每⼀个更新建⽴的顺序来分配给事务标识符

ZooKeeper:07---基础语法(会话:session)

  • 下图描述了在重连情况下事务标识符(zkid)的使⽤:
    • 当客户端因超时与s1断开连接后,客户端开始尝试连接s2,但s2延迟于客户端所知的变化
    • 然⽽,s3对这个变化的情况与客户端保持⼀致,所以s3可以安全连接

ZooKeeper:07---基础语法(会话:session)