最近一直在看zookeeper的代码和文章。原因一个是项目越来越依赖zk, 我也要给同事们分享一下zk。 有些心得,觉得很有必要记下来。
本人接触java一年多时间,看java代码不是很深入,我且把看懂的和知道的写来了。
一. zookeeper 基本介绍
1)Why zookeeper?
它是ApacheHadoop的一个子项目,它主要用来解决分布式集群中应用系统的一致性问题,提供基于类似于文件系统的目录节点树方式的数据存储。除了数据存储,它还可以用来维护和监控你存储的数据的状态变化。从设计模式角度来它能看,Zookeeper是一个基于观察者模式设计的分布式服务管理框架,它负责存储和管理大家都关心的数据,然后接受观察者的注册,一旦这些数据的状态发生变化,Zookeeper就将负责通知那些已经注册的观察者做出相应的反应。
3)What zk looks like?
上面说过,类似于文件系统, 是文件系统模型。 有图为证:
不过它的目录节点可以存少量数据(<1M)。
4) How ZK Work?
看图就知道大概了:
具体zk内部怎么运作的,且看下面的分解(成说书的了)
5) ZK 3个角色4个状态
6) zk node的类型
7) zk 的客户端API
大致有:
8)zk watcher
注意以下几点:
• One-time trigger, 只触发一次。再次需要再次注册,注册方式为再次getData(),exists(),getChildren()
以上的内容为对Zk的基本介绍。
二: Paxos算法
在ZK里, 和paxos算法对应的是
1) Leader Election: LeaderElection是Fastpaxos最简单的一种实现, 每个Server启动以后都询问其它的Server它要投票给谁,收到所有Server回复以后,就计算出zxid最大的哪个Server,作为下一次投票server
2) Fast Leader Election:FastLeaderElection是标准的fastpaxos的实现,它首先向所有Server提议自己要成为leader,当其它Server收到提议以后,解决epoch和zxid的冲突,并接受对方的提议,然后向对方发送接受提议完成的消息
三: zk的客户端
1)ZK的java Client。
由三个主要模块组成:Zookeeper, WatcherManager, ClientCnxn。如图:
•Zookeeper: 是ZK Client端的真正接口,用户可以操作的最主要的类,用户不用关心怎么连接到Server,Watcher什么时候被触发问题。
•WatcherManager: 是用来管理Watcher的,Watcher是ZK的一大特色功能,允许多个Client对一个或多个ZNode进行监控,当ZNode有变化时能够通知到监控这个ZNode的各个Client。
•ClientCnxn: 是管理所有网络IO的模块,所有和ZK Server交互的信息和数据都经过这个模块,包括给ZK Server发送Request,从ZK Server接受Response,以及从ZK Server接受Watcher Event。ClientCnxn完全管理了网络,从外部看来网络操作是透明的。
2)ZK的c client。
每个客户端由zhandle创建两个线程,IO线程(do_io)负责连接zk server以及收发包,competion线程(do_competion)处理异步回调函数和watcher调用。
主要缺点:
1.每初始化一个zhandle都会启动两个线程,线程不能共享。
2.c代码难以维护
3.回调串行处理,某个回调时间长容易堵住线程,可以采用线程池。
4.session expire必须由客户端重连到服务端才能发现。
5.重连时不sleep,因此实际应用中发生过DDOS
3)Python客户端
官方提供的python 客户端对C Client 有依赖。通过python调用libzookeeper_mt.so 和 libzookeeper_st.so动态库文件
4)zk watcher
•getData,getChildren(),exists()这三个方法可以针对参数中的path设置watcher,
•当path对应的Node 有相应变化时,server端会给对应的设置了watcher的client 发送一个一次性的触发通知事件。
•客户端在收到这个触发通知事件后,可以根据自己的业务逻辑进行相应地处理。