ZooKeeper---译名为“动物园管理员”。动物园里当然有好多的动物,游客可以根据动物园提供的向导图到不同的场馆观赏各种类型的动物,而不是像走在原始丛林里,心惊胆颤的被动 物所观赏。为了让各种不同的动物呆在它们应该呆的地方,而不是相互串门,或是相互厮杀,就需要动物园管理员按照动物的各种习性加以分类和管理,这样我们才能更加放心安全的观赏动物。
回到企业级应用系统中,随着信息化水平的不断提高,企业级系统变得越来越庞大臃肿,性能急剧下降,客户抱怨频频。拆分系统是目前我们可选择的解决系统可伸缩性和性能问题的唯一行之有效的方法。但是拆分系统同时也带来了系统的复杂性——各子系统不是孤立存在的,它们彼此之间需要协作和交互,这就是我们常说的分布式系统0。各个子系统就好比动物园里的动物,为了使各个子系统能正常为用户提供统一的服务,必须需要一种机制来进行协调——这就是ZooKeeper(动物园管理员)。
Zookeeper的设计目的
我们知道要写一个分布式应用是非常困难的,主要原因就是局部故障。一个消息通过网络在两个节点之间传递时,网络如果发生故障,发送方并不知道接收方是否接收到了这个消息。他可能在网络故障迁就收到了此消息,也坑没有收到,又或者可能接收方的进程死了。发送方了解情况的唯一方法就是再次连接发送方,并向他进行询问。这就是局部故障:根本不知道操作是否失败。因此,大部分分布式应用需要一个主控、协调控制器来管理物理分布的子进程。目前,大部分应用需要开发私有的协调程序,缺乏一个通用的机制。协调程序的反复编写浪费,且难以形成通用、伸缩性好的协调器。协调服务非常容易出错,并很难从故障中恢复。例如:协调服务很容易处于竞态1甚至死锁2。Zookeeper的设计目的,是为了减轻分布式应用程序所承担的协调任务。
Zookeeper并不能阻止局部故障的发生,因为它们的本质是分布式系统。他当然也不会隐藏局部故障。ZooKeeper的目的就是提供一些工具集,用来建立安全处理局部故障的分布式应用。
ZooKeeper是一个分布式小文件系统,并且被设计为高可用性。通过选举算法和集群复制可以避免单点故障3,由于是文件系统,所以即使所有的ZooKeeper节点全部挂掉,数据也不会丢失,重启服务器之后,数据即可恢复。另外ZooKeeper的节点更新是原子的,也就是说更新不是成功就是失败。通过版本号,ZooKeeper实现了更新的乐观锁4,当版本号不相符时,则表示待更新的节点已经被其他客户端提前更新了,而当前的整个更新操作将全部失败。当然所有的一切ZooKeeper已经为开发者提供了保障,我们需要做的只是调用API。与此同时,随着分布式应用的的不断深入,需要对集群管理逐步透明化监控集群和作业状态,可以充分利ZK的独有特性。
Zookeeper简介
①Zookeeper是Google的Chubby一个开源的实现,是Hadoop的分布式协调服务
②它包含一个简单的原语集,分布式应用程序可以基于它实现同步服务,配置维护和命名维护等
③它的文件系统使用了我们所熟悉的目录树结构。
④Zookeeper的设计目的是为了减轻分布式应用程序所承担的协调任务
Zookeeper集群
ZK集群如下图2.1所示。这是实际应用的一个场景,该ZooKeeper集群当中一共有5台服务器,有两种角色Leader和Follwer,5台服务器连通在一起,客户端有分别连在不同的ZK服务器上。如果当数据通过客户端1,在左边第一台Follower服务器上做了一次数据变更,他会把这个数据的变化同步到其他所有的服务器,同步结束之后,那么其他的客户端都会获得这个数据的变化。
注意:
通常Zookeeper由2n+1台servers组成,每个server都知道彼此的存在。每个server都维护的内存状态镜像以及持久化存储的事务日志和快照。为了保证Leader选举能过得到多数的支持,所以ZooKeeper集群的数量一般为奇数。对于2n+1台server,只要有n+1台(大多数)server可用,整个系统保持可用。
2.3.1 集群中的角色
在ZooKeeper集群当中,集群中的服务器角色有两种Leader和Learner,Learner角色又分为Observer和Follower,具体功能如下:
1.领导者(leader),负责进行投票的发起和决议,更新系统状态
2.学习者(learner),包括跟随者(follower)和观察者(observer),
3.follower用于接受客户端请求并向客户端返回结果,在选主过程中参与投票
4.Observer可以接受客户端请求,将写请求转发给leader,但observer不参加投票过程,只同步leader的状态,observer的目的是为了扩展系统,提高读取速度。
<