Zookeeper 是什么
zookeeper 是软件世界里的管理者,被用来 提供分布式环境的协调服务。zookeeper 是 yahoo 公司使用 java 语言开发的,是 Hadoop 项目中的子项目,基于 Google 的 Chubby 的开源实现,在 Hadoop,Hbase,Kafka 等技术中充当核心组件的角色。
它的设计目标就是 将那些复杂并且容易出错的分布式一致性服务加以封装,构成高效且可靠的服务,并为用户提供一系列简单易用的接口。
Zookeeper 是一个经典的 分布式数据一致性 解决方案,分布式应用程序可以基于它实现
- 数据的发布和订阅
- 负载均衡
- 命名服务
- 分布式协调与通知
- 集群管理
- 领导选举
- 分布式锁
- 分布式队列
zookeeper 一般都以 集群的方式 对外提供服务,一个集群包含多个节点,每个节点都对应一台 Zookeeper 服务器,所有的节点共同对外提供服务。具体包括以下五大特性:
- 顺序性
- 原子性
- 一致性
- 可靠性
- 实时性
Zookeeper 树状模型
Zookeeper 内部拥有树状的内存模型,与文件系统非常类似。
- 在 Zookeeper 中将这些目录与文件统称为 ZNode
- 每个 ZNode 都有对应的路径及其包含的数据
- ZNode 可由 Zookeeper 客户端来创建
- 当客户端与服务端建立连接后,服务端将为客户端创建一个 Session (会话),客户端对 ZNode 的所有操作均在这个会话中来完成
树状模型图如下所示
ZNode 包含 4 类节点
- persistent 持久节点
- persistent sequential 持久性顺序节点
- ephemeral 临时性节点
- ephemeral sequential 临时性顺序节点
Zookeeper 集群结构
Zookeeper 设计了一个轻量级的协议 Zab (ZooKeeper Atomic Broadcast, Zookeeper 广播协议)。Zab 协议分为两个阶段:
-
Leader Election 领导选举
Zookeeper 集群启动时,会选出一台节点为 Leader,而其他节点均为 Follower。当 Leader 出现故障时,会自动选举出新的 Leader 节点,并让所有节点恢复到一个正常的状态。选举结束后,会进入 原子广播阶段。
-
Atomic Broadcase 原子广播
该阶段会同步 Leader 节点与 Follower 节点之间的数据,确保 Leader 与 Follower 节点具有相同的状态。所有的写操作都会发送到 Leader 节点,并通过广播的方式同步到 Follower 节点。
一个 Zookeeper 集群通常由一组节点组成,一般情况下 3 ~ 5 个就可以组成可用的 Zookeeper 集群。
每个节点都会在内存中维护当前的服务器状态,并在每个节点之间都会保持通信,目的就是告诉其他节点“自己还活着”。我们一般会提供奇数个节点比较节省资源。此外, Zookeeper 客户端可以选择集群中任意一个节点来建立连接,而一旦客户端与某个节点之间断开联系,客户端会自动连接到集群的其他节点。
如何使用 ZooKeeper
zookeeper 官方地址:http://zookeeper.apache.org/
zookeeper 使用 java 语言开发,使用前需要先安装 jdk。下文是在 linux 环境下运行 zookeeper 的指导。
运行 Zookeeper
步骤1 修改 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 * tickTime -
syncLimit
用来配置 Leader 节点与 Follower 节点之间心跳检测的最大延时时间,默认值是 5,也就是 5 * tickTime -
dataDir
用来配置 Zookeeper 服务器存储快照文件的目录,不建议将其指定到 /tmp 目录下,因为该目录下的所有文件可能被自动删除。在 Zookeeper 环境中,将生成一个名为 myid 的文件,用来存放 zk 集群节点的 ID。 -
clientPort
用于配置当前 zk 服务器对外暴露的接口
步骤 2, 启动 Zookeeper 服务器
启动 Zookeeper 服务器非常简单,只需执行 Zookeeper 提供的脚本程序即可。
bin/zkServer.sh start
执行上面脚本,默认会在后台启动 Zookeeper 服务器。
zkServer.sh
可以传入以下参数
- start
- start-foreground
- stop
- restart
- status
- upgrade
- print-cmd
步骤 3, 验证 Zookeeper 服务是否有效
bin/zkServer.sh status
还可以使用 telnet 命令来验证 ZooKeeper 服务是否有效
telnet 127.0.0.1 2181
zookeeper 当前处于 standard alone 模式下,一般情况下我们使用单机模式作为开发环境,而使用集群模式作为生产环境。
搭建 Zookeeper 集群环境
在本地搭建一个伪集群模式的 Zookeeper 集群环境(3 个节点)
修改 Zookeeper 配置文件
配置如下
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>
- id 表示节点编号,表示该节点在集群中的唯一编号,取值在 0 ~ 255 之间。
- 必须在 dataDir 目录下创建一个名为 myid 的文件,其内容是该节点的编号
- ip 表示节点所在的 IP 地址,本机为 127.0.0.1 或者是 localhost
- port1 表示 Leader 节点与 Follower 节点心跳检测与数据同步时使用的接口
- port2 表示在领导选举过程中,用于投票通信的端口
启动 ZooKeeper 集群
与单机模式的启动方法相同,只需一次启动所有的 ZooKeeper 节点即可启动整个集群
验证 Zookeeper 集群环境是否有效
和 standard alone 模式一样,也可以通过 zkServer.sh 脚本与 telnet 命令来查看每个节点的状态,此时会看到 Mode:leader
或者 Mode:follower
的信息,表示该节点是 Leader 还是 Follower。
ZooKeeper 提供了一系列脚本程序,全部存放在 bin 目录下,如
- zkServer.sh 用于启动 Zookeeper 服务器
- zkCli.sh 用于连接 ZooKeeper 服务器的命令行客户端
- zkCleanup.sh 用于清理 ZooKeeper 的历史数据,包括
- 事务日志文件
- 快照数据文件
- zkEnv.sh 用于设置 ZooKeeper 的环境变量
连接 zookeeper
使用 zkCli 连接 Zookeeper
连接 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
表示最后一次修改节点时的事务 ID -
mtime
表示最后一次修改节点的时间 -
pZxid
表示最后一次修改父节点时的事务 ID -
cversion
子节点的版本号 -
dataVersion
节点包含数据的版本号 -
aclVersion
表示节点的 ACL 权限版本号 -
ephemeralOwner
临时节点的会话 ID -
dataLength
表示节点包含数据内容的长度 -
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 Client 连接 Zookeeper
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
可执行的常见操作包括:
- 列出子节点
- 判断节点是否存在
- 创建节点
- 获取节点数据
- 更新节点数据
- 删除节点
参考
- 《架构探险—轻量级微服务架构》
zookeeper 知识点汇总的更多相关文章
-
nginx几个知识点汇总
WHY? 为什么用Nginx而不用LVS? 7点理由足以说明一切:1 .高并发连接: 官方测试能够支撑 5 万并发连接,在实际生产环境中跑到 2 - 3 万并发连接数.?2 .内存消耗少: 在 3 万 ...
-
python全栈开发 * 10知识点汇总 * 180612
10 函数进阶 知识点汇总 一.动态参数 形参的第三种1.动态接收位置传参 表达:*args (在参数位置编写 * 表⽰接收任意内容) (1)动态位置参数def eat(*args): print(a ...
-
清华大学OS操作系统实验lab1练习知识点汇总
lab1知识点汇总 还是有很多问题,但是我觉得我需要在查看更多资料后回来再理解,学这个也学了一周了,看了大量的资料...还是它们自己的80386手册和lab的指导手册觉得最准确,现在我就把这部分知识做 ...
-
c++ 函数知识点汇总
c++ 函数知识点汇总 swap函数 交换两个数组元素 比如 swap(a[i],a[j]); 就是交换a[i] 和 a[j] 的值 strcpy() 复制一个数组元素的值到另一个数组元素里 strc ...
-
前端开发 JavaScript 干货知识点汇总
很多初学的朋友经常问我,前端JavaScript都需要学习哪些东西呀?哪些是JavaScript的重点知识啊? 其实做前端开发工程师,所有的知识点都是我们学习必备的东西,只有扎实的技术基础才是高薪的关 ...
-
BBS项目知识点汇总
目录 bbs项目知识点汇总 一. JavaScript 1 替换头像 2 form表单拿数据 3 form组件error信息渲染 4 添加html代码 5 聚焦操作 二 . html在线编辑器 三 . ...
-
Java面试知识点汇总
Java面试知识点汇总 置顶 2019年05月07日 15:36:18 温柔的谢世杰 阅读数 21623 文章标签: 面经java 更多 分类专栏: java 面试 Java面试知识汇总 版权声明 ...
-
离散数学 II(最全面的知识点汇总)
离散数学 II(知识点汇总) 目录 离散数学 II(知识点汇总) 代数系统 代数系统定义 例子 二元运算定义 运算及其性质 二元运算的性质 封闭性 可交换性 可结合性 可分配性 吸收律 等幂性 消去律 ...
-
我要进大厂之大数据ZooKeeper知识点(2)
01 我们一起学大数据 接下来是大数据ZooKeeper的比较偏架构的部分,会有一点难度,老刘也花了好长时间理解和背下来,希望对想学大数据的同学有帮助,也特别希望能够得到大佬的批评和指点. 02 知识 ...
随机推荐
-
《微软互联网信息服务(IIS) 最佳实践》已上市,欢迎选购!
本书内容涵盖了IIS6.0~IIS 10.0 的全部主流IIS 版本,是多年微软技术支持经验的结晶.祝您顺利排除Web 服务器的疑难杂症! 本书由微软亚太区全球技术支持中心IIS 方面的顶尖专家金鑫作 ...
-
Ajax提交参数的值中带有html标签不能提交成功的解决办法(ASP.NET)
最近在公司做资源及文章上传功能遇到一个小问题,被坑了好半天. 该功能就类似利用富文本编辑器发布信息,但是用Ajax提交数据,因此提交参数值中不可避免的含有html标签. 在本地运行代码一直没问题,总是 ...
-
openstack中eventlet使用
openstack中使用eventlet的协程来实现并发. 第一种,使用eventlet.GreenPool来管理绿色线程 如l3-agent在开启了8个绿色线程来处理router消息 def _pr ...
-
eclipse 编译android程序 编译错误
windows->show view -> problems, 这个窗口的内容即为 编译错误的内容.
-
HashMap其实就那么一回事儿之源码浅析
上篇文章<LinkedList其实就那么一回事儿之源码分析>介绍了LinkedList, 本次将为大家介绍HashMap. 在介绍HashMap之前,为了方便更清楚地理解源码,先大致说说H ...
-
iOS7 隐藏状态栏 hide statusBar
1.调用 [self setNeedsStatusBarAppearanceUpdate]; 2.重载以下函数 - (BOOL)prefersStatusBarHidden{ return _hide ...
-
Keil C动态内存管理机制分析及改进
Keil C是常用的嵌入式系统编程工具,它通过init_mempool.mallloe.free等函数,提供了动态存储管理等功能.本文通过对init_mempool.mallloe和free这3个Ke ...
-
二 Djano模型层之模型字段选项
字段选项 以下参数是全部字段类型都可用的,而且是可选的 null 如果为True,Django将在数据库中将空值存储为NULL.默认值为False 对于字符串字段,如果设置了null=True意味着& ...
-
sip 注册流程
基本注册流程示意图: 注册流程描述如下: 1. SIP代理向SIP服务器发送REGISTER请求: 2. SIP服务器向SIP代理发送响应401,并在响应的消息头WWW ...
-
P2176 [USACO14FEB]路障Roadblock
题目描述 每天早晨,FJ从家中穿过农场走到牛棚.农场由 N 块农田组成,农田通过 M 条双向道路连接,每条路有一定长度.FJ 的房子在 1 号田,牛棚在 N 号田.没有两块田被多条道路连接,以适当的路 ...