ZooKeeper Server/Client Session 设计及代码分析

 
学习开源项目,首要应该是了解其机制。拿来主义固然可以加速开发,但是也会带来潜在的风险。如果你想把自己的应用做的好,你需要保证每一次汲取的营养都是精华,而尽量不要引入糟粕。最近有很多分布式的研发,所以了解了一下ZooKeeper,我们来看看有什么有趣的东西。

ZooKeeper用了不少代码维护ZK client和ZK server之间的session。基本架构是一个NIO  server,后面是processer序列,一个NIO请求,先由PreProcessor处理,最后由FinalProcessor处理。中间可能根据情况加入其它processor。这有点像apache servlet的设计概念,但我个人一向不喜欢这种逻辑表达。作为web servlet容器还可以,但作为应用server,这极度弱化了面向对象概念。应该立即将NIO请求转化为对象,再由对象自行,或交予适合的handler处理对象,而不是将所有请求看为一个流。

通常session意味着有状态保持,可是ZooKeeper的session只有owner和timeout,这根本不是状态。那么Sesion到底是干什么用的呢?看看ZooKeeper官方文档上怎么说的,

When a client gets a handle to the ZooKeeper service, ZooKeeper creates a ZooKeeper  session, represented as a 64-bit number, that it assigns to the client. If the client  connects to a different ZooKeeper server, it will send the session id as a part of  the connection handshake. As a security measure, the server creates a password for  the session id that any ZooKeeper server can validate.The password is sent to the  client with the session id when the client establishes the session. The client sends  this password with the session id whenever it reestablishes the session with a new  server.

ZooKeeper Session re-connection是有一个password校验,可是该password在每个Server上都由相同的code产生,也就是说,只要是ZooKeeper服务器,有一个算一个,password都能通过。这个feature似乎可有可无?

One of the parameters to the ZooKeeper client library call to create a ZooKeeper  session is the session timeout in milliseconds. The client sends a requested timeout,  the server responds with the timeout that it can give the client. The current  implementation requires that the timeout be a minimum of 2 times the tickTime (as set  in the server configuration) and a maximum of 20 times the tickTime.

这似乎是session唯一确实有效的机制,但这和维护一个NIO channel并无多大区别。不同只在于不同ZooKeeper client可以有不同的timeout。

Another parameter to the ZooKeeper session establishment call is the default watcher.  Watchers are notified when any state change occurs in the client. For example if the  client loses connectivity to the server the client will be notified, or if the  client's session expires, etc... This watcher should consider the initial state to be  disconnected (i.e. before any state changes events are sent to the watcher by the  client lib). In the case of a new connection, the first event sent to the watcher is  typically the session connection event.

Watcher的解释与实际代码不符合。文档上说有其他实现,但code我只看到One-time trigger。这个很简单,当client发起请求时,加个watcher标签。Server更新DataTree之后便向client端发一个TCP response。在实现上,ZooKeeper NIOServerCnxn implements Watcher,Watcher直接注册到DataTree上,key是path。

Watcher设计的实现的结果非常类似于RPC。即client/server端封装同样的WatcherEvent,这样Client端直接监听WatcherEvent,就好像直接从Server端扔出的event一样。不过我个人以为,还是使用通用的通讯协议,用XML,JSON或直接byte,例如RTSP,在client自己解析好。因为这样更灵活些,扩展性更好些。

总之,ZooKeeper client/server session没什么意思。还有很多非常有趣的漏洞,

首先,为了检查session timeout,居然每个session extends Thread!虽然默认只有10个client连接,但该值可配。这是很危险的,Thread数超过1024,JVM调度就不大灵光了。另外NIOServerCnxn中处理NIO的Factory居然只有单线程在跑。而且整个后台处理设计也是基于单线程的。PrepRequestProcessor使用一个LinkedBlockingQueue处理request。本来用LinkedBlockingQueue是个好主意,但是只有一个线程在处理它。显然是太少了。而且SessionTrackerImpl处加了太多没有必要的同步锁,本来就是单线程处理,要同步锁干什么?


我估计ZooKeeper的核心应该还是Paxos算法的实现。下面会接着看。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值