分布式协调技术,主要用来解决分布式环境当中多个进程之间的同步控制,让他们有序的去访问某种临界资源,防止形成"脏数据"的后果。
ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,是Google的Chubby一个开源的实现,是Hadoop和Hbase的重要组件。它是一个为分布式应用提供一致性服务的软件,提供的功能包括:配置维护、域名服务、分布式同步、组服务等。它提供了一项基本服务:分布式锁服务。
ZooKeeper是以Fast Paxos算法为基础的,Paxos 算法存在活锁的问题,即当有多个proposer交错提交时,有可能互相排斥致使没有一个proposer能提交成功,而Fast Paxos做了一些优化,经过选举产生一个leader (领导者),只有leader才能提交proposer。node
在Zookeeper中,znode是一个跟Unix文件系统路径类似的节点,能够往这个节点存储或获取数据。若是在建立znode时Flag设置为EPHEMERAL,那么当建立这个znode的节点和Zookeeper失去链接后,这个znode将再也不存在在Zookeeper里,Zookeeper使用Watcher察觉事件信息。当客户端接收到事件信息,好比链接超时、节点数据改变、子节点改变,能够调用相应的行为来处理数据。
ZooKeeper所提供的服务主要是经过:数据结构+原语+watcher机制,三个部分来实现的。算法
ZooKeeper的数据模型,在结构上和标准文件系统的很是类似,都是采用这种树形层次结构,ZooKeeper树中的每一个节点被称为—Znode。和文件系统的目录树同样,ZooKeeper树中的每一个节点能够拥有子节点。
经过路径引用,且要求时绝对路径。数据库
zookeeper有9个基本的操做,这些操做时有限制的,同时操做时非阻塞的。网络
ZooKeeper能够为全部的读操做设置watch数据结构
数据watch(data watches):getData和exists负责设置数据watch
孩子watch(child watches):getChildren负责设置孩子watch分布式
传统的准备方案,实现方式是,备用节点向主节点发ping,主节点收到ping后给回复ACK消息,若是备用节点收不到ACK消息则认为主节点挂掉,启动备节点的上的实例,接替成为主节点,但若是是网络不可靠致使的ACK消息无法正常收到则会产生双主的问题,致使服务混乱。
引入Zookeeper后,启动的主节点A,B会向zk注册,再进行选举出主节点,其余的则成为被阻塞的备用节点,若是主节点挂掉,则会自动删掉其在zk中的注册节点,zk感知节点变化,再次选举新的leader做为主节点。若是有新节点注册,仍是经过选举leader的方式确保只有一个主节点。oop
Zoopkeeper 提供了一套很好的分布式集群管理的机制,就是它这种基于层次型的目录树的数据结构,并对树中的节点进行有效管理,从而能够设计出多种多样的分布式的数据管理模型优化
分布式应用中,一般须要有一套完整的命名规则,既可以产生惟一的名称又便于人识别和记住,一般状况下用树形的名称结构是一个理想的选择,树形的名称结构是一 个有层次的目录结构,既对人友好又不会重复。说到这里你可能想到了 JNDI,没错 Zookeeper 的 Name Service 与 JNDI 可以完成的功能是差很少的,它们都是将有层次的目录结构关联到必定资源上,可是 Zookeeper 的 Name Service 更加是普遍意义上的关联,也许你并不须要将名称关联到特定资源上,你可能只须要一个不会重复名称,就像数据库中产生一个惟一的数字主键同样。spa
配置的管理在分布式应用环境中很常见,例如同一个应用系统须要多台 PC Server 运行,可是它们运行的应用系统的某些配置项是相同的,若是要修改这些相同的配置项,那么就必须同时修改每台运行这个应用系统的 PC Server,这样很是麻烦并且容易出错。像 这样的配置信息彻底能够交给 Zookeeper 来管理,将配置信息保存在 Zookeeper 的某个目录节点中,而后将全部须要修改的应用机器监控配置信息的状态,一旦配置信息发生变化,每台应用机器就会收到 Zookeeper 的通知,而后从 Zookeeper 获取新的配置信息应用到系统中。设计
Zookeeper 不只可以帮你维护当前的集群中机器的服务状态,并且可以帮你选出一个“总管”,让这个总管来管理集群,这就是 Zookeeper 的另外一个功能 Leader Election。
Zookeeper 却很容易实现这个功能,实现方式也是须要得到锁的 Server 建立一个 EPHEMERAL_SEQUENTIAL 目录节点,而后调用 getChildren方法获取当前的目录节点列表中最小的目录节点是否是就是本身建立的目录节点,若是正是本身建立的,那么它就得到了这个锁,若是不是那么它就调用 exists(String path, boolean watch) 方法并监控 Zookeeper 上目录节点列表的变化,一直到本身建立的节点是列表中最小编号的目录节点,从而得到锁,释放锁很简单,只要删除前面它本身所建立的目录节点就好了。