ZooKeeper介绍

ZooKeeper作为一个分布式的服务框架,主要用来解决分布式集群中应用系统的一致性问题,它能提供基于类似于文件系统的目录节点树方式的数据存储。但是ZooKeeper并不是用来专门存储数据的,它主要用来维护和监控存储数据状态的变化。通过监控这些数据状态的变化,可以达到基于数据的集群管理。

ZooKeeper是一个开放源码的分布式应用程序协调服务,它包含一个简单的原语集,是Hadoop和HBase的重要组件。分布式应用可以使用它来实现诸如统一命名服务、配置管理、分布式锁服务、集群管理等功能。

ZooKeeper通过一种和文件系统类似的层级命名空间来让分布式进程相互协调工作。这些命名空间由一系列数据寄存器组成,这些数据寄存器称为znodes。这些znodes有点像文件系统中的文件和文件夹。和文件系统不一样的是,文件系统中的文件是存储在存储区上,而ZooKeeper的数据是存储在内存中的,这就意味着ZooKeeper有着高吞吐和低延迟的特性。

ZooKeeper实现了高性能、高可靠性和有序的访问。高性能保证了ZooKeeper能应用在大型分布式系统上;高可靠性保证它不会由于单一节点的故障而造成任何问题;有序的访问能保证客户端实现较为复杂的同步操作。

组成ZooKeeper的各个服务器必须能相互通信。它们在内存中保存了服务器状态,也保存了操作的日志,并且持久化快照。只要大多数服务器是可用的,那么ZooKeeper就是可用的。

客户端连接到一个ZooKeeper服务器,并且维持TCP连接,发送请求,获取回复,获取事件,同时发送连接信号。如果这个TCP连接中断了,那么客户端可以连接另外一个服务器。

ZooKeeper使用数字来对每一个更新进行标记,这样就能保证ZooKeeper交互的有序,后续操作可以按照这个顺序实现诸如同步操作这样更高、更抽象的服务。

ZooKeeper的高效主要表现在以读为主的系统上。ZooKeeper可以在千台服务器组成的读/写比例约为10:1的分布系统上表现优异。

ZooKeeper命名空间的结构和文件系统很像。名字和文件系统一样使用“/”的路径形式,ZooKeeper的每个节点都是被路径唯一标识的数据结构和分等级的命名空间。

Zookeeper从设计模式角度来看,是一个基于观察者模式设计的分布式服务管理框架,它负责存储和管理用户都关心的数据,然后接受观察者的注册,一旦这些数据的状态发生变化,Zookeeper将负责通知已经在Zookeeper上注册的那些观察者做出相应的反应,从而实现集群中类似Master/Slave的管理模式。

在分布式应用中,通常需要有一套完整的命名规则,既能够产生唯一的名称,又便于识别和记忆。通常情况下用树形的名称结构是一个理想的选择。树形的名称结构是一个有层次的目录结构,既对用户友好又不会重复。Zookeeper的Name Service与JNDI能够功能是差不多的,它们都是将有层次的目录结构关联到一定资源上。Name Service已经是Zookeeper内置的功能,只要调用API就能实现,如调用cretae接口就可以很容易地创建一个目录结点。

配置管理:将配置信息保存在Zookeeper的某个目录结点中,然后将所有需要修改的应用机器监控配置信息的状态,一旦配置信息发生变化,每台应用机器就会收到Zookeeper的通知,然后从Zookeeper获取新的配置信息应用到系统中。

集群管理:Zookeeper中的实现方式都是在Zookeeper上创建一个EPHEMERAL类型的目录节点,然后每个server在它们创建目录结点的父目录结点上调用getChildren(String path,Boolean watch)方法并设置watch为true。由于是EPHEMERAL目录节点,当创建它的server死去时,这个目录结点也随之被删除,这是children将会变化,调用getChildren方法设置watch为false,所以其他Server就知道已经有某台Server死去了。新增Server也是同样的道理。Zookeeper如何实现Leader Election,也就是选出一个Master Server?和前面一样,每台Server创建一个EPHEMERAL目录节点,不同的是它还是一个SEQUENTIAL目录结点,所以它是一个EPHEMERAL_SEQUENTIAL目录节点。之所以它是EPHEMERAL_SEQUENTIAL目录节点,是因为我们可以给每台Server编号,可以选择当前最小编号的Server为Master.假如这个最小编号的Server死去,由于是EPHEMERAL节点,死去的Server对应的节点也被删除,所以当前的节点列表中又出现一个最小编号的节点,我们就选择这个节点为当前Master。这样就实现了动态选择Master,避免了传统意义上单Master容易出现单点故障的问题。

共享锁(Locks):实现方式也是需要获得锁的Server创建一个EPHEMERAL_SEQUENTIAL目录节点,然后调用getChildren方式获得当前目录节点列表中最小的目录节点是不是自己创建的目录节点。如果正是自己创建的,那么它就获得了这个锁;如果不是,那么它就调用exists(String path,boolean watch)方法并监控ZooKeeper上目录节点列表的变化,一直到自己创建的节点是列表中最小编号的目录节点,从而获得锁。释放锁很简单,只要删除前面自己创建的目录节点即可。

队列管理:ZooKeeper可以处理两种类型的队列,第一是当一个队列的成员都聚集时,这个队列才可用,否则一直等待所有成员到达,这种是同步队列。第二是队列按照FIFO方式进行入队和出队操作,如实现生产者和消费者模型。

同步队列的实现思路:创建一个父目录/synchronizing,每个成员都监控标志(Set Watch)位目录/synchronizing/start是否存在,然后每个成员都加入这个队列。加入队列的方式就是创建/synchronizing/member_i的临时目录节点,然后每个成员获取/synchronizing目录的所有目录节点,也就是member_i。判断i的值是否已经是成员的个数,如果小于成员个数则等待/synchronizing/start的出现,如果已经相等就创建/synchronizing/start。

FIFO队列用ZooKeeper实现的思路:就是在特定的目录下创建SEQUENTIAL类型的子目录/queue_i,这样就能保证所有成员加入队列时都是有编号的,出队列时通过getChildren()方法可以返回当前所有队列中的元素,然后消费其中最小的一个,这样就能保证FIFO。


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值