目录javascript
zookeeper 是软件世界里的管理者,被用来 提供分布式环境的协调服务。zookeeper 是 yahoo 公司使用 java 语言开发的,是 Hadoop 项目中的子项目,基于 Google 的 Chubby 的开源实现,在 Hadoop,Hbase,Kafka 等技术中充当核心组件的角色。java
它的设计目标就是 将那些复杂而且容易出错的分布式一致性服务加以封装,构成高效且可靠的服务,并为用户提供一系列简单易用的接口。node
Zookeeper 是一个经典的 分布式数据一致性 解决方案,分布式应用程序能够基于它实现linux
zookeeper 通常都以 集群的方式 对外提供服务,一个集群包含多个节点,每一个节点都对应一台 Zookeeper 服务器,全部的节点共同对外提供服务。具体包括如下五大特性:shell
Zookeeper 内部拥有树状的内存模型,与文件系统很是相似。apache
树状模型图以下所示npm
ZNode 包含 4 类节点服务器
Zookeeper 设计了一个轻量级的协议 Zab (ZooKeeper Atomic Broadcast, Zookeeper 广播协议)。Zab 协议分为两个阶段:session
Leader Election 领导选举架构
Zookeeper 集群启动时,会选出一台节点为 Leader,而其余节点均为 Follower。当 Leader 出现故障时,会自动选举出新的 Leader 节点,并让全部节点恢复到一个正常的状态。选举结束后,会进入 原子广播阶段。
Atomic Broadcase 原子广播
该阶段会同步 Leader 节点与 Follower 节点之间的数据,确保 Leader 与 Follower 节点具备相同的状态。全部的写操做都会发送到 Leader 节点,并经过广播的方式同步到 Follower 节点。
一个 Zookeeper 集群一般由一组节点组成,通常状况下 3 ~ 5 个就能够组成可用的 Zookeeper 集群。
每一个节点都会在内存中维护当前的服务器状态,并在每一个节点之间都会保持通讯,目的就是告诉其余节点“本身还活着”。咱们通常会提供奇数个节点比较节省资源。此外, Zookeeper 客户端能够选择集群中任意一个节点来创建链接,而一旦客户端与某个节点之间断开联系,客户端会自动链接到集群的其余节点。
zookeeper 官方地址:http://zookeeper.apache.org/
zookeeper 使用 java 语言开发,使用前须要先安装 jdk。下文是在 linux 环境下运行 zookeeper 的指导。
Zookeeper 默认提供了一份名为 zoo_sample.cfg
的示例配置文件,须要复制一下,并将其重命名为 zoo.cfg
。配置文件的重要配置项以下
tickTime=2000 initLimit=10 syncLimit=5 dataDir=/tmp/zookeeper clientPort=2181
详细解释下以上配置项
tickTime
滴答时间,用于配置 Zookeeper 中最小时间单元的长度。单位为 ms。默认值是 3000 ms。initLimit
用于配置 Leader 节点等待 Follower 节点启动并完成数据同步的时间, 默认值是 10 ,也就是 10 * tickTimesyncLimit
用来配置 Leader 节点与 Follower 节点之间心跳检测的最大延时时间,默认值是 5,也就是 5 * tickTimedataDir
用来配置 Zookeeper 服务器存储快照文件的目录,不建议将其指定到 /tmp 目录下,由于该目录下的全部文件可能被自动删除。在 Zookeeper 环境中,将生成一个名为 myid 的文件,用来存放 zk 集群节点的 ID。clientPort
用于配置当前 zk 服务器对外暴露的接口启动 Zookeeper 服务器很是简单,只需执行 Zookeeper 提供的脚本程序便可。
bin/zkServer.sh start
执行上面脚本,默认会在后台启动 Zookeeper 服务器。
zkServer.sh
能够传入如下参数
bin/zkServer.sh status
还可使用 telnet 命令来验证 ZooKeeper 服务是否有效
telnet 127.0.0.1 2181
zookeeper 当前处于 standard alone 模式下,通常状况下咱们使用单机模式做为开发环境,而使用集群模式做为生产环境。
在本地搭建一个伪集群模式的 Zookeeper 集群环境(3 个节点)
配置以下
tickTime=2000 initLimit=10 syncLimit=5 dataDir=/usr/local/app-data/zookeeper/data dataLogDir=/usr/local/zookeeper-3.4.6/logs clientPort=2181 server.0=127.0.0.1:2888:3888 server.1=127.0.0.1:2889:3889 server.2=127.0.0.1:2890:3890
与单机模式的区别就在于添加了一组 server 配置,表示集群中包含的三个节点,须要注意的是 server 配置须要知足必定的格式:
server.<id>=<ip>:<port1>:<port2>
与单机模式的启动方法相同,只需一次启动全部的 ZooKeeper 节点便可启动整个集群
和 standard alone 模式同样,也能够经过 zkServer.sh 脚本与 telnet 命令来查看每一个节点的状态,此时会看到 Mode:leader
或者 Mode:follower
的信息,表示该节点是 Leader 仍是 Follower。
ZooKeeper 提供了一系列脚本程序,所有存放在 bin 目录下,如
链接 ZooKeeper 只须要执行如下脚本:
bin/zkCli.sh
若是想要链接远程的 ZooKeeper, 则在 zkCli.sh 脚本中添加 -server 选项
bin/zkCli.sh -server <ip>:<port>
链接成功后,就能够输入相关的命令来操做 zookeeper 了。当输入 help 命令后,将输出 zookeeper 相关客户端命令的使用帮助。
ZooKeeper -server host:port cmd args stat path [watch] set path data [version] ls path [watch] delquota [-n|-b] path ls2 path [watch] setAcl path acl setquota -n|-b val path history redo cmdno printwatches on|off delete path [version] sync path listquota path rmr path get path [watch] create [-s] [-e] path data acl addauth scheme auth quit getAcl path close connect host:port
命令格式以下
ls path [watch]
ls 命令中可设置一个 watch
参数,用于指定客户端监视器,在 zooKeeper 中被称为 Watcher, Watcher 用于监控节点的状态变化,默认状况下可不带有任何 Watcher。
[zk: localhost:2181(CONNECTED) 0] ls / [zookeeper]
默认状况下,根目录中有一个名为 zookeeper 的子节点,它做为 Zookeeper 的保留节点,咱们通常不使用它。
此外,还可使用 ls2
命令以更加详细的方式列出节点名称及其相关属性,命令格式以下
ls2 path [watch]
ls2 命令会输出当前节点的基本信息
[zk: localhost:2181(CONNECTED) 2] ls2 / [zookeeper] cZxid = 0x0 ctime = Thu Jan 01 08:00:00 CST 1970 mZxid = 0x0 mtime = Thu Jan 01 08:00:00 CST 1970 pZxid = 0x0 cversion = -1 dataVersion = 0 aclVersion = 0 ephemeralOwner = 0x0 dataLength = 0 numChildren = 1
在输出信息中包含了大量的统计属性:
cZxid
表示建立节点时的事务 ID (每一个客户端请求都会造成一个事务)ctime
表示建立节点的时间mZxid
表示最后一次修改节点时的事务 IDmtime
表示最后一次修改节点的时间pZxid
表示最后一次修改父节点时的事务 IDcversion
子节点的版本号dataVersion
节点包含数据的版本号aclVersion
表示节点的 ACL 权限版本号ephemeralOwner
临时节点的会话 IDdataLength
表示节点包含数据内容的长度numChildren
当前节点的子节点数[zk: localhost:2181(CONNECTED) 8] stat /foo Node does not exist: /foo
使用 create 命令建立节点,命令格式以下
create [-s] [-e] path data acl
其中
-s
用于指定该节点是否为顺序节点,即 Sequential 节点
-e
选项:用于指定该节点是否为临时节点,即 Ephemeral 节点
acl
用于权限控制, Zookeeper 内部提供了一个强大的 ACL 访问控制列表,默认状况下不作任何权限控制
[zk: localhost:2181(CONNECTED) 13] create -e /foo hello Created /foo
使用 get 命令获取节点数据,命令格式以下
get path [watch]
能够经过如下命令获取 /foo 节点包含的数据
[zk: localhost:2181(CONNECTED) 14] get /foo hello cZxid = 0xa ctime = Wed Jan 02 15:27:44 CST 2019 mZxid = 0xa mtime = Wed Jan 02 15:27:44 CST 2019 pZxid = 0xa cversion = 0 dataVersion = 0 aclVersion = 0 ephemeralOwner = 0x1680d4a324f0002 dataLength = 5 numChildren = 0
使用 set 命令更新节点数据,命令格式以下
set path data [version]
在更新节点数据时,可指定 version 参数,表示节点包含数据的版本号。若是不指定 version 参数,则表示更新节点数据的最新版本。
使用 delete 命令删除节点,命令格式以下
delete path [version]
当节点没有任何子节点时,才能删除成功,不然将给出 "node not empty" 的提示,但能够经过如下命令一次删除该节点及其全部的子节点。
rmr path
Node.js 链接 Zookeeper 中比较好用的客户端是 node-zookeeper-client
。
首先经过 NPM 来安装这个模块。
npm install node-zookeeper-client
先用一段代码来展现链接 Zookeeper, 后面再基于该代码,将 nodejs 针对 zookeeper 客户端的操做执行一遍。
var zookeeper = require('node-zookeeper-client') var CONNECTION_STRING = 'localhost:2181' var OPTIONS = { sessionTimeout: 5000 } var zk = zookeeper.createClient(CONNECTION_STRING, OPTIONS) zk.on('connected', function() { console.log(zk); zk.close(); }); zk.connect();
若是 zk 能够正常输出,说明可成功链接 Zookeeper 服务器并创建了正常的会话, 下面全部的操做都在该会话中进行。Node.js 客户端仅提供了异步方式,咱们不能经过同步方式来调用。
node-zookeeper-client 的官方文档地址为: https://www.npmjs.com/package/node-zookeeper-client
可执行的常见操做包括: