1 Zookeeper简介
ZooKeeper最为主要的使?场景,是作为分布式系统的分布式协同服务。
分布式系统的协调?作就是通过某种?式,让每个节点的信息能够同步和共享。这依赖于服务进程之间 的通信。通信?式有两种: ZooKeeper对分布式系统的协调,使?的是第?种?式,共享存储。其实共享存储,分布式应?也需要 和存储进??络通信。 注:Slave节点要想获取ZooKeeper的更新通知,需事先在关?的数据节点上设置观察点。
?多数分布式系统中出现的问题,都源于信息的共享出了问题。如果各个节点间信息不能及时共享和同 步,那么就会在协作过程中产?各种问题。ZooKeeper解决协同问题的关键,就是在于保证分布式系统 信息的?致性。
zookeeper的基本概念
Zookeeper是?个开源的分布式协调服务,其设计?标是将那些复杂的且容易出错的分布式?致性服务 封装起来,构成?个?效可靠的原语集,并以?些简单的接?提供给?户使?。 zookeeper是?个典型 的分布式数据?致性的解决?案,分布式应?程序可以基于 它实现诸如数据订阅/发布、负载均衡、命名 服务、集群管理、分布式锁和分布式队列等功能
基本概念    
2 Zookeeper基本使?
2.1 ZooKeeper系统模型
在ZooKeeper中,数据信息被保存在?个个数据节点上,这些节点被称为znode。ZNode 是 Zookeeper 中最?数据单位,在 ZNode 下??可以再挂 ZNode,这样?层层下去就形成了?个层次化 命名空间 ZNode 树,我们称为 ZNode Tree,它采?了类似?件系统的层级树状结构进?管理。?下图 示例:

在 Zookeeper 中,每?个数据节点都是?个 ZNode,上图根?录下有两个节点,分别是:app1 和 app2,其中 app1 下??有三个?节点,所有ZNode按层次化进?组织,形成这么?颗树,ZNode的节 点路径标识?式和Unix?件系统路径?常相似,都是由?系列使?斜杠(/)进?分割的路径表示,开 发?员可以向这个节点写?数据,也可以在这个节点下?创建?节点。

 ZNode 的状态信息  Watcher–数据变更通知
Zookeeper使?Watcher机制实现分布式数据的发布/订阅功能 ?个典型的发布/订阅模型系统定义了?种 ?对多的订阅关系,能够让多个订阅者同时监听某?个主题 对象,当这个主题对象?身状态变化时,会通知所有订阅者,使它们能够做出相应的处理。 在 ZooKeeper 中,引?了 Watcher 机制来实现这种分布式的通知功能。ZooKeeper 允许客户端向服务 端注册?个 Watcher 监听,当服务端的?些指定事件触发了这个 Watcher,那么就会向指定客户端发 送?个事件通知来实现分布式的通知功能。
整个Watcher注册与通知过程如图所示。 Zookeeper的Watcher机制主要包括客户端线程、客户端WatcherManager、Zookeeper服务器三部 分。
具体?作流程为:客户端在向Zookeeper服务器注册的同时,会将Watcher对象存储在客户端的 WatcherManager当中。当Zookeeper服务器触发Watcher事件后,会向客户端发送通知,客户端线程 从WatcherManager中取出对应的Watcher对象来执?回调逻辑。
ACL–保障数据的安全
Zookeeper作为?个分布式协调框架,其内部存储了分布式系统运?时状态的元数据,这些元数据会直 接影响基于Zookeeper进?构造的分布式系统的运?状态,因此,如何保障系统中数据的安全,从?避 免因误操作所带来的数据随意变更?导致的数据库异常?分重要,在Zookeeper中,提供了?套完善的 ACL(Access Control List)权限控制机制来保障数据的安全。 我们可以从三个??来理解ACL机制:权限模式(Scheme)、授权对象(ID)、权限 (Permission),通常使?"scheme: id : permission"来标识?个有效的ACL信息。   权限 权限就是指那些通过权限检查后可以被允许执?的操作。在ZooKeeper中,所有对数据的操作权限分为 以下五?类: · CREATE(C):数据节点的创建权限,允许授权对象在该数据节点下创建?节点。 · DELETE(D): ?节点的删除权限,允许授权对象删除该数据节点的?节点。 · READ(R):数据节点的读取权限,允 许授权对象访问该数据节点并读取其数据内容或?节点列表等。 · WRITE(W):数据节点的更新权 限,允许授权对象对该数据节点进?更新操作。 · ADMIN(A):数据节点的管理权限,允许授权对象 对该数据节点进? ACL 相关的设置操作。
2.2 ZooKeeper命令?操作


创建顺序节点
使? create -s /zk-test 123 命令创建zk-test顺序节点
创建临时节点
使? create -e /zk-temp 123 命令创建zk-temp临时节
创建永久节点
使? create /zk-permanent 123 命令创建zk-permanent永久节点
读取节点


更新节点
使?set命令,可以更新指定节点的数据内容,?法如下
set path data [version]
其中,data就是要更新的新内容,version表示数据版本,在zookeeper中,节点的数据是有版本概 念的,这个参数?于指定本次更新操作是基于Znode的哪?个数据版本进?的,如将/zk-permanent节 点的数据更新为456,可以使?如下命令:set /zk-permanent 456
删除节点
使?delete命令可以删除Zookeeper上的指定节点,?法如下
delete path [version]
其中version也是表示数据版本,使?delete /zk-permanent 命令即可删除/zk-permanent节点
2.3 Zookeeper-开源客户端
2.3.1 ZkClient
ZkClient是Github上?个开源的zookeeper客户端,在Zookeeper原?API接?之上进?了包装,是?个 更易?的Zookeeper客户端,同时,zkClient在内部还实现了诸如Session超时重连、Watcher反复注册 等功能
pom.xml增加
<dependency>
<groupId>com.101tec</groupId>
<artifactId>zkclient</artifactId> <version>0.2</version>
</dependency>
创建会话
ZkClient zkClient = new ZkClient("127.0.0.1:2181");
创建节点
ZkClient提供了递归创建节点的接?,即其帮助开发者先完成?节点的创建,再创建?节点
ZkClient zkClient = new ZkClient("127.0.0.1:2181");
zkClient.createPersistent("/test-Client/test-c1",true);
删除节点
ZkClient提供了递归删除节点的接?,即其帮助开发者先删除所有?节点(存在),再删除?节点。
String path = "/test-Client/test-c1";
ZkClient zkClient = new ZkClient("127.0.0.1:2181", 5000);
zkClient.deleteRecursive(path);
获取?节点
ZkClient zkClient = new ZkClient("127.0.0.1:2181", 5000);
boolean exists = zkClient.exists(path);
if (!exists){
zkClient.createEphemeral(path, "123");
}
zkClient.subscribeDataChanges(path, new IZkDataListener() {
public void handleDataChange(String path, Object data) throwsException {
System.out.println(path+"该节点内容被更新,更新后的内容"+data);
}
public void handleDataDeleted(String s) throws Exception {
System.out.println(s+" 该节点被删除");
}
});
Object o = zkClient.readData(path);
System.out.println(o);
zkClient.writeData(path,"4567");
Thread.sleep(1000);
zkClient.delete(path);
Thread.sleep(1000);

2.3.2 Curator客户端
curator是Net?ix公司开源的?套Zookeeper客户端框架,和ZKClient?样,Curator解决了很多 Zookeeper客户端?常底层的细节开发?作,包括连接重连,反复注册Watcher和 NodeExistsException异常等,是最流?的Zookeeper客户端之?。从编码?格上来讲,它提供了基于 Fluent的编程?格?持
pom.xml
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>2.12.0</version>
</dependency>
创建会话
    
创建节点

删除节点

获取数据

更新数据
更新数据,如果未传?version参数,那么更新当前最新版本,如果传?version则更新指定version,如 果version已经变更,则抛出异常。

3 Zookeeper应?场景
ZooKeeper是?个典型的发布/订阅模式的分布式数据管理与协调框架,我们可以使?它来进?分布式 数据的发布与订阅。另???,通过对ZooKeeper中丰富的数据节点类型进?交叉使?,配合Watcher 事件通知机制,可以?常?便地构建?系列分布式应?中都会涉及的核?功能,如数据发布/订阅、命名 服务、集群管理、Master选举、分布式锁和分布式队列等。
数据发布/订阅
数据发布/订阅(Publish/Subscribe)系统,即所谓的配置中?,顾名思义就是发布者将数据发布到 ZooKeeper的?个或?系列节点上,供订阅者进?数据订阅,进?达到动态获取数据的?的,实现配置 信息的集中式管理和数据的动态更新。
发布/订阅系统?般有两种设计模式,分别是推(Push)模式和拉(Pull)模式。在推模式中,服务端 主动将数据更新发送给所有订阅的客户端;?拉模式则是由客户端主动发起请求来获取最新数据,通常 客户端都采?定时进?轮询拉取的?式。
ZooKeeper 采?的是推拉相结合的?式:客户端向服务端注册??需要关注的节点,?旦该节点的数据 发?变更,那么服务端就会向相应的客户端发送Watcher事件通知,客户端接收到这个消息通知之后, 需要主动到服务端获取最新的数据。
如果将配置信息存放到ZooKeeper上进?集中管理,那么通常情况下,应?在启动的时候都会主动到 ZooKeeper服务端上进??次配置信息的获取,同时,在指定节点上注册?个Watcher监听,这样? 来,但凡配置信息发?变更,服务端都会实时通知到所有订阅的客户端,从?达到实时获取最新配置信 息的?的。 
命名服务
命名服务(Name Service)也是分布式系统中?较常?的?类场景,是分布式系统最基本的公共服务之 ?。在分布式系统中,被命名的实体通常可以是集群中的机器、提供的服务地址或远程对象等——这些 我们都可以统称它们为名字(Name),其中较为常?的就是?些分布式服务框架(如RPC、RMI)中 的服务地址列表,通过使?命名服务,客户端应?能够根据指定名字来获取资源的实体、服务地址和提 供者的信息等。 ZooKeeper 提供的命名服务功能能够帮助应?系统通过?个资源引?的?式来实现对资源的定位与使 ?。另外,?义上命名服务的资源定位都不是真正意义的实体资源——在分布式环境中,上层应?仅仅 需要?个全局唯?的名字,类似于数据库中的唯?主键。  
集群管理
随着分布式系统规模的?益扩?,集群中的机器规模也随之变?,那如何更好地进?集群管理也显得越 来越重要了。所谓集群管理,包括集群监控与集群控制两?块,前者侧重对集群运?时状态的收集,后 者则是对集群进?操作与控制。
  
   
Master选举
Master选举是?个在分布式系统中?常常?的应?场景。分布式最核?的特性就是能够将具有?计算 能?的系统单元部署在不同的机器上,构成?个完整的分布式系统。?与此同时,实际场景中往往也需 要在这些分布在不同机器上的?系统单元中选出?个所谓的“??”,在计算机中,我们称之为 Master。 在分布式系统中,Master往往?来协调集群中其他系统单元,具有对分布式系统状态变更的决定权。例 如,在?些读写分离的应?场景中,客户端的写请求往往是由 Master来处理的;?在另?些场景中, Master则常常负责处理?些复杂的逻辑,并将处理结果同步给集群中其他系统单元。Master选举可以 说是ZooKeeper最典型的应?场景了
分布式锁
分布式锁是控制分布式系统之间同步访问共享资源的?种?式。如果不同的系统或是同?个系统的不同 主机之间共享了?个或?组资源,那么访问这些资源的时候,往往需要通过?些互斥?段来防?彼此之 间的?扰,以保证?致性,在这种情况下,就需要使?分布式锁了。
排他锁
排他锁(Exclusive Locks,简称 X 锁),?称为写锁或占锁,是?种基本的锁类型。如果事务 T1对 数据对象 O1加上了排他锁,那么在整个加锁期间,只允许事务 T1对 O1进?读取和更新操作,其他任 何事务都不能再对这个数据对象进?任何类型的操作——直到T1释放了排他锁  
共享锁
共享锁(Shared Locks,简称S锁),?称为读锁,同样是?种基本的锁类型。 如果事务T1对数据对象O1加上了共享锁,那么当前事务只能对O1进?读取操作,其他事务也只能对这 个数据对象加共享锁——直到该数据对象上的所有共享锁都被释放。 共享锁和排他锁最根本的区别在于,加上排他锁后,数据对象只对?个事务可?,?加上共享锁后,数 据对所有事务都可?。 
分布式队列
分布式队列可以简单分为两?类:?种是常规的FIFO先?先出队列模型,还有?种是 等待队列元素聚 集后统?安排处理执?的Barrier模型。
FIFO先?先出
FIFO(First Input First Output,先?先出), FIFO 队列是?种?常典型且应??泛的按序执?的队列 模型:先进?队列的请求操作先完成后,才会开始处理后?的请求。  Barrier:分布式屏障 Barrier原意是指障碍物、屏障,?在分布式系统中,特指系统之间的?个协调条件,规定了?个队列的 元素必须都集聚后才能统?进?安排,否则?直等待。这往往出现在那些?规模分布式并?计算的应? 场景上:最终的合并计算需要基于很多并?计算的?结果来进?。这些队列其实是在 FIFO 队列的基础 上进?了增强,?致的设计思想如下:开始时,/queue_barrier 节点是?个已经存在的默认节点,并且 将其节点的数据内容赋值为?个数字n来代表Barrier值,例如n=10表示只有当/queue_barrier节点下的 ?节点个数达到10后,才会打开Barrier。之后,所有的客户端都会到/queue_barrie节点下创建?个临 时节点,例如/queue_barrier/host1,如图所示。 
4 Zookeeper深?进阶
ZAB协议
ZAB协议并不像Paxos算法那样 是?种通?的分布式?致性算法,它是?种特别为zookeeper专?设计 的?种?持崩溃恢复的原??播协议
在zookeeper中,主要就是依赖ZAB协议来实现分布式数据的?致性,基于该协议,Zookeeper实现了 ?种主备模式的系统架构来保持集群中各副本之间的数据的?致性,表现形式就是 使??个单?的主进 程来接收并处理客户端的所有事务请求,并采?ZAB的原??播协议,将服务器数据的状态变更以事务 Proposal的形式?播到所有的副本进程中,ZAB协议的主备模型架构保证了同?时刻集群中只能够有? 个主进程来?播服务器的状态变更,因此能够很好地处理客户端?量的并发请求。但是,也要考虑到主 进程在任何时候都有可能出现崩溃退出或重启现象,因此,ZAB协议还需要做到当前主进程当出现上述异 常情况的时候,依旧能正常?作。  ZAB与Paxos的联系和区别 
服务器??
Leader服务器是Zookeeper集群?作的核?,其主要?作有以下两个: (1) 事务请求的唯?调度和处理者,保证集群事务处理的顺序性。 (2) 集群内部各服务器的调度者。
Follower服务器是Zookeeper集群状态中的跟随者,其主要?作有以下三个: (1) 处理客户端?事务性请求(读取数据),转发事务请求给Leader服务器。 (2) 参与事务请求Proposal的投票。 (3) 参与Leader选举投票。
Observer是ZooKeeper?3.3.0版本开始引?的?个全新的服务器??。从字?意思看,该服务器充当 了?个观察者的??——其观察ZooKeeper集群的最新状态变化并将这些状态变更同步过来。 Observer服务器在?作原理上和Follower基本是?致的,对于?事务请求,都可以进??的处理,? 对于事务请求,则会转发给Leader服务器进?处理。和Follower唯?的区别在于,Observer不参与任 何形式的投票,包括事务请求Proposal的投票和Leader选举投票。简单地讲,Observer服务器只提供 ?事务服务,通常?于在不影响集群事务处理能?的前提下提升集群的?事务处理能?。
leader选举
Leader选举是zookeeper最重要的技术之?,也是保证分布式数据?致性的关键所在。 当Zookeeper集群中的?台服务器出现以下两种情况之?时,需要进?Leader选举。 (1) 服务器初始化启动。 (2) 服务器运?期间?法和Leader保持连接。
|