ZooKeeper:是一个分布式的,开放源码的分布式应用程序协调服务,是Google的Chubby一个开源的实现,是Hadoop和Hbase的重要组件。
他主要用来解决分布式应用中的数据管理的一致性问题。例如统一命名服务、状态同步服务、集群管理、分布式应用配置项的管理等。
官网:http://hadoop.apache.org/zookeeper/。
Zookeeper 从设计模式角度来看,是一个基于观察者模式设计的分布式服务管理框架,它负责存储和管理大家都关心的数据,然后接受观察者的注册,一旦这些数据的状态发生变化,Zookeeper 就将负责通知已经在 Zookeeper 上注册的那些观察者做出相应的反应,从而实现集群中类似 Master/Slave 管理模式。
zk server
zookeeper本身是分布式部署的,各个节点数据都放在内存中,且各节点保持一致,server之间通过定时发送心跳消息感知健康状态。
各个节点会选出一个leader server,其它的服务节点成为followers。 所有的写请求会被转到leader server来处理,然后再通知followers节点更新状态;读请求则可由followers直接处理。由于写操作需要进行全局同步,所以Zookeeper更适合读多写少类型的应用。
zookeeper集群管理的核心是原子广播,这个机制保障了各个server之间的数据一致性。实现这个机制的协议叫做Zab协议,包括广播模式和恢复模式
如何在众多server中选举出一个leader,需要一个合适的算法。
zk健康检测
客户端和服务端建立连接之后,会话随之建立,生成一个全局唯一的SessionID,客户端和服务器端维护长连接。在SessionID的周期内,服务器会检测与客户端的连接是否正常(客户端定时向服务器发送心跳消息,服务器重置SessionTimeout时间)
zk数据管理
Zookeeper对分布式任务的协同调度,是以管理分布式任务数据来实现的。
Zookeeper数据模型结构与Unix文件系统很类似,是一个树状层次结构。
(图片来源http://www.ibm.com/developerworks/cn/opensource/os-cn-zookeeper/)
1、每个子目录项如 NameService 都被称作为 znode,这个 znode 是被它所在的路径唯一标识,如 Server1 这个 znode 的标识为 /NameService/Server1
2、znode 可以有子节点目录,并且每个znode 可以存储数据
3、znode 可以是临时节点,一旦创建这个 znode 的客户端与服务器失去联系,这个znode 也将自动删除,Zookeeper 的客户端和服务器通信采用长连接方式,每个客户端和服务器通过心跳来保持连接,这个连接状态称为 session,如果 znode 是临时节点,这个 session 失效,znode也就删除了
4、znode 可以被监控(设置Watcher),包括这个目录节点中存储的数据的修改,子节点目录的变化等,一旦变化可以通知设置该Watcher的客户端,从而每个客户端都很快知道它所关注的目录节点的状态发生变化,而做出相应的反应。这个是 Zookeeper 的核心特性,Zookeeper 的很多功能都是基于这个特性实现的。
应用场景
1、统一命名服务(Name Service):
阿里的架Dubbo中使用ZooKeeper来作为其命名服务,维护全局的服务地址列表。服务提供者在启动的时候,向ZK上的指定节点/dubbo/${serviceName}/providers目录下写入自己的URL地址,这个操作就完成了服务的发布。服务消费者启动的时候,订阅/dubbo/${serviceName}/providers目录下的提供者URL地址, 并向/dubbo/${serviceName} /consumers目录下写入自己的URL地址。所有向ZK上注册的地址都是临时节点,这样就能够保证服务提供者和消费者能够自动感应资源的变化。
(1)zk客户端连接zk服务器(发布者)
(2)发布者客户端调用create方法在zk server上创建目录节点,同时将服务属性写入目录节点的数据中
(3)zk客户端连接zk服务器(消费者)
(4)消费者客户端从服务器获取服务地地址和属性信息,同时设置watcher来监控跟这个目录节点的数据。获得服务的信息之后, 更新到本地缓存中。
(5)消费者监听服务提供者的目录列表,当有服务上下线的时候,可以获得通知
(6)发布者调用create动态注册新服务
(7)消费者获取新服务上线通知,获取新的服务地址,并更新到本地缓存
(8)发布者取消服务,只要delete目录即可,同时删除了目录相关的数据
(9)消费者受到服务下线通知,获取下线的信息,并从本地缓存中删除
(10)zk客户端与服务器的连接会话终止,存储在zk上的所有临时数据与注册的订阅者都被自动移除
(11)消费者获取服务列表被删除的通知之后,更新本地缓存路由表
2、配置管理(Configuration Management)
将配置信息保存在 Zookeeper 的某个目录节点中,然后将所有需要修改的应用机器监控配置信息的状态,一旦配置信息发生变化,每台应用机器就会收到 Zookeeper 的通知,然后从 Zookeeper 获取新的配置信息应用到系统中。
3、集群管理(Group Membership)
Zookeeper 能够很容易的实现集群管理的功能,如有多台 Server 组成一个服务集群,那么必须要一个“总管”知道当前集群中每台机器的服务状态,一旦有机器不能提供服务,集群中其它集群必须知道,从而做出调整重新分配服务策略。同样当增加集群的服务能力时,就会增加一台或多台 Server,同样也必须让“总管”知道。
它们的实现方式都是在 Zookeeper 上创建一个 EPHEMERAL 类型的目录节点,然后每个 Server 在它们创建目录节点的父目录节点上调用 getChildren(String path, boolean watch) 方法并设置 watch 为 true,由于是 EPHEMERAL 目录节点,当创建它的 Server 死去,这个目录节点也随之被删除,所以 Children 将会变化,这时 getChildren上的 Watch 将会被调用,所以其它 Server 就知道已经有某台 Server 死去了。新增 Server 也是同样的原理。
4、分布式锁
虽然Zookeeper没有原生提供锁操作,但是通过Zookeeper提供的一些API, 较容易实现分布式锁。我们可以利用临时节点来实现,多个进程都尝试创键临时节点/lock, 但最终只会有一个进程P能创建成功,而其他没能创建成功的进程,可以在节点/lock上Watch(相当于等待锁释放), 一旦进程P处理完事务,断开连接,节点/lock被自动删除,其他进程将得到通知,进而继续创建节点/lock,以争得锁资源。 (这里使用临时节点,是为了防止获得锁的进程突然崩溃而没有释放锁,导致死锁发生)。
5、管理队列
参考文档:
http://www.techweb.com.cn/network/hardware/2015-12-25/2246973.shtml
http://blog.csdn.net/yanlinwang/article/details/45080455
http://www.ibm.com/developerworks/cn/opensource/os-cn-zookeeper/
t.hao0.me