英文版名称:ZooKeeper: Distributed Process Coordination
第1章 简介
当你决定使用ZooKeeper来设计应用时,最好将应用数据和协同数据独立开。
比如:网路邮箱服务的用户对自己邮箱中的内容感兴趣,但是并不关心由哪台服务器来处理特定邮箱的请求。在这个例子中,邮箱内容就是应用数据,而从邮箱到某一台邮箱服务器之间的映射关系就是协同数据(或称元数据)。整个ZooKeeper服务所管理的就是后者。
1.1 ZooKeeper的使命
- Apache Hbase
HBase是一个通常与Hadoop一起使用的数据存储仓库。在HBase中,ZooKeeper用于选举一个集群内的主节点,以便跟踪可用的服务器,并保存集群的元数据。
- 关于ZooKeeper名字的来源
ZooKeeper was developed at Yahoo! Research. We had been working on ZooKeeper for a while and pitching it to other groups, so we needed a name. At the time the group had been working with the Hadoop team and had started a variety of projects with the names of animals, Apache Pig being the most well known. As we were talking about different possible names, one of the group members mentioned that we should avoid another animal name because our manager thought it was starting to sound like we lived in a zoo. That is when it clicked: distributed systems are a zoo. They are chaotic and hard to manage, and ZooKeeper is meant to keep them under control.
The cat on the book cover is also appropriate, because an early article from Yahoo! Research about ZooKeeper described distributed process management as similar to herding cats. ZooKeeper sounds much better than CatHerder, though.
- 整个ZooKeeper的服务器集群管理着应用协作的关键数据。ZooKeeper不适合用作海量数据存储。
第2章 了解ZooKeeper
2.1 ZooKeeper基础
- ZooKeeper并不直接暴露原语,取而代之,它暴露了由一小部分调用方法组成的类似文件系统的API,以便允许应用实现自己的原语。我们通常使用菜谱(recipes)来表示这些原语的实现。菜谱包括ZooKeeper操作和维护一个小型的数据节点,这些节点被称为znode,采用类似于文件系统的层级树状结构进行管理。
- API
- create /path data
创建一个名为/path的znode节点,并包含数据data,-e参数标志创建的znode为临时节点。
- delete /path
删除名为/path的znode。
- exists /path
检查是否存在名为/path的节点。
- setData /path data
设置名为/path的znode的数据为data。
- getData /path
返回名为/path的节点的数据信息。
- getChildren /path
返回所有/path节点的所有子节点列表,注:不含子节点的子节点。
- 注:ZooKeeper并不允许局部写入或读取znode节点的数据。当设置一个znode节点的数据或读取时,znode节点的内容会被整个替换或全部读取进来。
- stat /path [true]
stat命令可以得到一个znode节点/path的属性,并允许我们在已经存在的znode节点上设置监视点。通过在路径后面设置参数true来添加监视点。比如可以监控节点删除事件NodeDeleted事件。
- ls /path [true]
可以查看/path下的子节点,通过设置true这个参数,可以设置对应znode的子节点变化的监视点。
- znode的不同类型
- 持久(persistent)节点和临时(ephemeral)节点
持久的znode只能通过调用delete来进行删除。临时的znode与之相反,当创建该节点的客户端崩溃或关闭了与ZooKeeper的连接时,整个节点就会被删除。通过-e参数创建临时节点。
- 有序节点,通过-s参数创建有序节点
- 监视与通知
客户端向ZooKeeper注册需要接收通知的znode,通过对znode设置监视点(watch)来接收通知。监视点是一个单词触发的操作,意即监视点会触发一个通知。为了接收多个通知,客户端必须在每次通知后设置一个新的监视点。
- 版本
每一个znode 都有一个版本号,它随着每次数据变化而自增。两个API操作可以有条件地执行:setData和delete。这个两个调用以版本号作为传入参数,只有当传入参数的版本号与服务器上的版本号一致时调用才会成功。
2.2 ZooKeeper架构
ZooKeeper服务器端运行于两种模式下:独立模式(standalone)和仲裁模式(quorum)。
2.3 开始使用ZooKeeper
- windows注意事项
- 使用如下命令运行时报如下错误,解决方法,不带start参数,但是无法stop,只能通过Ctrl+c停止,仔细查看了windows脚本和Linux脚本,发现windows脚本太弱了,想深入学习的话还是转战Linux。
D:\soft\zookeeper-3.4.8\bin>zkServer.cmd start
D:\soft\zookeeper-3.5.1-alpha\bin>zkServer.cmd start
系统找不到指定的路径。
Error: JAVA_HOME is incorrectly set.
- 如果报上述错误(在zookeeper-3.5.1-alpha中出现),说明您的JAVA_HOME路径中有空格,只需修改bin/zkEnv.cmd文件,在
%JAVA_HOME%
外面增加双引号即可,如下所示:
if not exist "%JAVA_HOME%\bin\java.exe" (
echo Error: JAVA_HOME is incorrectly set.
)
set JAVA="%JAVA_HOME%\bin\java"
- 会话的状态和生命周期
- 事务标识符zkid
- 本节在Windows上开发,需要修改zkServer.cmd文件,将其中
java "-Dzookeeper.log.dir=%ZOO_LOG_DIR%" "-Dzookeeper.root.logger=%ZOO_LOG4J_PROP%" -cp "%CLASSPATH%" %ZOOMAIN% "%ZOOCFG%" %*
改为
java "-Dzookeeper.log.dir=%ZOO_LOG_DIR%" "-Dzookeeper.root.logger=%ZOO_LOG4J_PROP%" -cp "%CLASSPATH%" %ZOOMAIN% %*
即,去除"%ZOOCFG%"
,执行命令时手动指定配置文件*.cfg的路径。
- 实现一个原语:通过ZooKeeper实现锁
2.4 一个主-从模式例子的实现
通过zkCli工具来实现主-从示例的一些功能。
主-从模式的模型中包括三个角色:
- 主节点
主节点负责监视新的从节点和任务,分配任务给可用的从节点。
- 从节点
从节点会通过系统注册自己,以确保主节点看到它们可以执行任务,然后开始监视新任务。
- 客户端
客户端创建新任务并等待系统的响应。
第3章 开始使用ZooKeeper的API
注意:顺序和ConnectionLossException异常
ZooKeeper会严格维护执行顺序,并提供强有力的有序保障,然而,在多线程下还是需要小心面对顺序问题。多线程下,当回调函数中包括重试逻辑的代码时,一些常见的场景都可能导致错误发生。当遇到ConnectionLossException异常而补发一个请求时,新建立的请求可能排序在其他线程中的请求之后,而实际上其他线程中的请求应该在原来的请求之后。
第4章 处理状态变化