Zookeeper:服务器和会话

会话(Session)构成了Zookeeper中的一个重要抽象。顺序保证(Ordering guarantee),临时节点(Ephemeral znode)和Watch都与会话紧密耦合。因此,Session追踪机制(Session track mechnism)对于Zookeeper来说是非常重要的。( (这篇博客是Flavio Junqueria和Benjamin Reed的Zookeeper书的第9章中Servers and Sessions的翻译)

Zookeeper服务器的一个重要任务就是持续追踪会话。在Standalone模式,一个服务器追踪所有的会话;而在Quorum模式,Leader追踪它们。事实上,Leader服务器和Standalone服务器运行着相同的会话追踪器(Session Tracker) (参考SessionTracker和SessionTrackerImpl)。Follower服务器仅仅是将所有客户端的会话信息转发给Leader(参考LearnerSessionTracker).

为了保持会话存活,服务器需要接收会话对应的心跳(Heartbeat)。心跳以新请求或显示的PING消息形式出现(参考LearnerHandler.run())。在这两种情况,服务器通过更新会话的失效时间来触摸(Touch)会话(参考SessionTrackerImpl.touchSession()),在Quorum模式,Leader发送PING消息给Learner,然后Learner返回自从上次PING消息后触摸到的会话列表。Leader每隔半个滴答(Tick)发送一个PING消息给Learner。滴答是Zookeeper用的最小时间单元,以毫秒表示。所以,如果滴答设置为2s,那么Leader每隔1s发送一个PING消息。

两个重要的点管理会话失效。为了实现会话失效,一个被称为失效队列(参考ExpiryQueue)的数据结构保存了会话信息。这个数据结构将会话保存在桶里,每个桶和一段会话被认为失效的时间范围相关联。Leader每次只将一个桶里的会话失效。为了决定是哪个桶失效,,当到了下一个会话失效的截止时间,一个线程会检查失效队列来找出失效的桶。这个线程会一直睡到截止时间。当这个线程苏醒,它会从失效队列中拉出新的一批会话, 并将它们失效。当然也可能拉出来是空的。

(expirationTime/expirationInterval + 1)*expirationInterval

为了提供一个例子,我们假设expirationInterval是2,并且会话的expirationTime发生在时间点10。我们将这个会话分配到桶12中((10/2+1)*2的结果)。注意,当我们触摸会话时,expirationTime会保持增长,所以由此我们可以将会话移到更晚失效的桶里。

使用桶模式的一个重要原因是为了减少会话失效检查的开销。Zookeeper部署可能有成千上万的客户端,以及由此而来的成千上万的Session。使用细粒度(Fine-grained)的会话失效检查方式不适合这种场景。与这个评论相关,注意如果expirationInterval很短,那么Zookeeper最终是使其实是用细粒度的方式进行会话失效检查。expirationInterval目前是一个滴答,而滴答通常是秒级的。

转载请附上原博客地址:

待人对事不要太计较,如果太计较就会有悔恨!

Zookeeper:服务器和会话

相关文章:

你感兴趣的文章:

标签云: