zookeeper是什么
zookeeper是源代码开放的分布式协调服务 ,由雅虎创建,是Google
Chubby的开源实现。zookeeper是一个高性能的分布式数据一致性解决方案 ,它将那些复杂的、容易出错的分布式一致性服务封装起来,构成一个高效可靠的原语集,并提供一系列简单易用的接口给用户使用
zookeeper 从设计模式角度来看,是一个基于观察者模式设计的分布式服务管理框架,它负责存储和管理大家都关心的数据,然后接受观察者的注册,一旦这些数据的状态发生变化,zookeeper 就将负责通知已经在 zookeeper 上注册的那些观察者做出相应的反应,从而实现集群中类似 Master/Slave 管理模式
知识要点
- 源代码开放
- 分布式协调服务,解决分布式数据一致性问题
- 顺序一致性
- 原子性
- 单一视图
- 可靠性
- 实时性
- 高性能
- 通过调用zookeeper提供的接口来解决一些分布式应用中的实际问题
zookeeper的典型应用场景
数据发布/订阅
数据发布/订阅 顾名思义就是一方把数据发布出来,另一方通过某种手段可以得到这些数据。通常数据订阅有两种方式:推模式和拉模式;推模式一般是服务器主动向客户端推送信息,拉模式是客户端主动去服务器获取数据(通常是采用定时轮询的方式)
ZK采用两种方式相结合
发布者将数据发布到ZK集群节点上,订阅者通过一定的方法告诉服务器,我对哪个节点的数据感兴趣,那服务器在这些节点的数据发生变化时,就通知客户端,客户端得到通知后可以去服务器获取数据信息
分布式协调/通知
心跳检测
在分布式系统中,我们常常需要知道某个机器是否可用,传统的开发中,可以通过Ping某个主机来实现,Ping得通说明对方是可用的,相反是不可用的,ZK 中我们让所有的机其都注册一个临时节点,我们判断一个机器是否可用,我们只需要判断这个节点在ZK中是否存在就可以了,不需要直接去连接需要检查的机器 ,降低系统的复杂度
统一命名服务(Name Service)
分布式应用中,通常需要有一套完整的命名规则,既能够产生唯一的名称又便于人识别和记住,通常情况下用树形的名称结构是一个理想的选择,树形的名称结构是一个有层次的目录结构,既对人友好又不会重复。说到这里你可能想到了 JNDI,没错 zookeeper 的 Name Service 与 JNDI 能够完成的功能是差不多的,它们都是将有层次的目录结构关联到一定资源上,但是 zookeeper 的 Name Service 更加是广泛意义上的关联,也许你并不需要将名称关联到特定资源上,你可能只需要一个不会重复名称,就像数据库中产生一个唯一的数字主键一样。
例如数据库表格ID,一般用得比较多的有两种ID,一种是自动增长的ID,一种是UUID(9291d71a-0354-4d8e-acd8-64f7393c64ae),两种ID各自都有缺陷,自动增长的ID局限在单库单表中使用,不能在分布式中使用,UUID可以在分布式中使用但是由于ID没有规律难于理解,我们可以借用ZK来生成一个顺序增长的,可以在集群环境下使用的,命名易于理解的ID
Name Service 已经是 zookeeper 内置的功能,你只要调用 zookeeper 的 API 就能实现。如调用 create 接口就可以很容易创建一个目录节点。
配置管理(Configuration Management)
配置的管理在分布式应用环境中很常见,例如同一个应用系统需要多台 PC Server 运行,但是它们运行的应用系统的某些配置项是相同的,如果要修改这些相同的配置项,那么就必须同时修改每台运行这个应用系统的 PC Server,这样非常麻烦而且容易出错。
像这样的配置信息完全可以交给 zookeeper 来管理,将配置信息保存在 zookeeper 的某个目录节点中,然后将所有需要修改的应用机器监控配置信息的状态,一旦配置信息发生变化,每台应用机器就会收到 zookeeper 的通知,然后从 zookeeper 获取新的配置信息应用到系统中。
集群管理(Group Membership)
zookeeper 能够很容易的实现集群管理的功能,如有多台 Server 组成一个服务集群,那么必须要一个“总管”知道当前集群中每台机器的服务状态,一旦有机器不能提供服务,集群中其它集群必须知道,从而做出调整重新分配服务策略。同样当增加集群的服务能力时,就会增加一台或多台 Server,同样也必须让“总管”知道。
zookeeper 不仅能够帮你维护当前的集群中机器的服务状态,而且能够帮你选出一个“总管”,让这个总管来管理集群,这就是 zookeeper 的另一个功能 Leader Election。
分布式锁
共享锁在同一个进程中很容易实现,但是在跨进程或者在不同 Server之间就不好实现了。zookeeper 却很容易实现这个功能
队列管理
zookeeper 可以处理两种类型的队列:
- 当一个队列的成员都聚齐时,这个队列才可用,否则一直等待所有成员到达,这种是同步队列。
- 队列按照 FIFO 方式进行入队和出队操作,例如实现生产者和消费者模型。
基本概念
集群角色
Leader,Follower,Observer
Leader服务器是整个zookeeper集群工作机制中的核心
Follower服务器是zookeeper集群状态的跟随者
Observer服务器充当一个观察者的角色
会话
会话是指客户端和zookeeper服务器的连接,zookeeper中的会话叫Session,客户端靠与服务器建立一个TCP的长连接
来维持一个Session,客户端在启动的时候首先会与服务器建立一个TCP连接,通过这个连接,客户端能够通过心跳检测与服务器保持有效的会话,也能向ZK服务器发送请求并获得响应
数据模型
zookeeper 会维护一个具有层次关系的数据结构,它非常类似于一个标准的文件系统

zookeeper 这种数据结构有如下这些特点:
- 每个子目录项如 NameService 都被称作为 znode,这个 znode 是被它所在的路径唯一标识,如 Server1 这个 znode 的标识为 /NameService/Server1
- znode 可以有子节点目录,并且每个 znode 可以存储数据,注意 EPHEMERAL 类型的目录节点不能有子节点目录
- znode 是有版本的,每个 znode 中存储的数据可以有多个版本,也就是一个访问路径中可以存储多份数据
- znode 可以是临时节点,一旦创建这个 znode 的客户端与服务器失去联系,这个 znode 也将自动删除,zookeeper 的客户端和服务器通信采用长连接方式,每个客户端和服务器通过心跳来保持连接,这个连接状态称为 session,如果 znode 是临时节点,这个 session 失效,znode 也就删除了
- znode 的目录名可以自动编号,如 App1 已经存在,再创建的话,将会自动命名为 App2
- znode 可以被监控,包括这个目录节点中存储的数据的修改,子节点目录的变化等,一旦变化可以通知设置监控的客户端,这个是 zookeeper 的核心特性,zookeeper 的很多功能都是基于这个特性实现的,后面在典型的应用场景中会有实例介绍
版本
version 当前数据节点数据内容的版本号
cversion 当前数据节点子节点的版本号
aversion 当前数据节点ACL变更版本号
ACL权限控制
ACL是Access Control Lists 的简写, zookeeper采用ACL策略来进行权限控制,有以下权限:
CREATE:创建子节点的权限
READ:获取节点数据和子节点列表的权限
WRITE:更新节点数据的权限
DELETE:删除子节点的权限
ADMIN:设置节点ACL的权限
