|
最近一直在看zookeeper的代码和文章。原因一个是项目越来越依赖zk, 我也要给同事们分享一下zk。 有些心得,觉得很有必要记下来。
本人接触java一年多时间,看java代码不是很深入,我且把看懂的和知道的写来了。
一. zookeeper 基本介绍
1)Why zookeeper?
一般分布式应用需要一个主控、协调器或控制器来管理物理分布的子进程;缺乏一个通用的机制;协调程序的反复编写浪费, 2)What Is Zookeeper ?
它是ApacheHadoop的一个子项目,它主要用来解决分布式集群中应用系统的一致性问题,提供基于类似于文件系统的目录节点树方式的数据存储。除了数据存储,它还可以用来维护和监控你存储的数据的状态变化。从设计模式角度来它能看,Zookeeper是一个基于观察者模式设计的分布式服务管理框架,它负责存储和管理大家都关心的数据,然后接受观察者的注册,一旦这些数据的状态发生变化,Zookeeper就将负责通知那些已经注册的观察者做出相应的反应。
3)What zk looks like?
上面说过,类似于文件系统, 是文件系统模型。 有图为证:
不过它的目录节点可以存少量数据(<1M)。
4) How ZK Work?
看图就知道大概了:
*All servers store a copy of the data (in memory) *A leader is elected at startup *Both followers and leaderservice clients, allupdates go through leader
具体zk内部怎么运作的,且看下面的分解(成说书的了)
5) ZK 3个角色4个状态
角色 –leader,主负责进行投票的发起和决议,最终更新状态 –follower, Follower用于接收客户请求并返回客户结果。参与Leader发起的投票。 –observer,Oberserver可接收客户端连接,将写请求转发给leader节点。但是Observer不参加投票过程,只是同步leader的状态 ·对应4个状态:leading, following , observing, looking
6) zk node的类型
·Persistent Nodes:永久有效地节点,除非client显式的删除,否则一直存在 ·Ephemeral Nodes:临时节点,仅在创建该节点client保持连接期间有效,一旦连接丢失,zookeeper会自动删除该节点 ·Sequence Nodes:顺序节点,client申请创建该节点时,zk会自动在节点路径末尾添加递增序号,这种类型是实现分布式锁,分布式queue岛上所有事情由议员(Senator)决定等特殊功能的关键
7) zk 的客户端API
大致有:
·ZooKeeper(StringconnectString,intsessionTimeout,Watcherwatcher) ·create(finalString path, byte data[], List<ACL>acl,CreateModecreateMode) ·exists(final String path,Watcherwatcher) ·setData(finalString path, byte data[],int version) ·getData(final String path,Watcherwatcher,Statstat) ·getChildren(final String path,Watcherwatcher)
8)zk watcher
All of the read operations:getData(),exists(),getChildren()提供watcher的功能, 分为data watches and child watches。
注意以下几点:
·One-time trigger, 只触发一次。再次需要再次注册,注册方式为再次getData(),exists(),getChildren()
·Sent to the client, 我理解为在客户端运行watcher的process函数。
以上的内容为对Zk的基本介绍。
二: Paxos算法
说paxos为zk的灵魂,一点也不为过。 对于分布式一致性算法来说,paxos比较成熟。先简单说一下paxos算法内容:说是有个叫paxos的岛,岛上住着一群岛民。岛上所有事情由议员(Senator)决策, 每个提议(Proposal)都有一个编号(PID),议员只会同意大于当前编号的提议。也只有一半以上议员同意,当前的提议才算通过。
在ZK里, 和paxos算法对应的是 ·小岛(Island)——ZK Server Cluster ·议员(Senator)——ZK Server ·提议(Proposal)——ZNode Change(Create/Delete/SetData…) ·提议编号(PID)——Zxid(ZooKeeper Transaction Id) ·正式法令——所有ZNode及其数据 zk paxos主要使用fast paxos(paxos一种演变), 有两个实现, leader election 和fast leader election。下面介绍这两个实现:
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 发送一个一次性的触发通知事件。
·客户端在收到这个触发通知事件后,可以根据自己的业务逻辑进行相应地处理。
|
|