Zookeeper 是什么

zookeeper 是软件世界里的管理者,被用来 提供分布式环境的协调服务。zookeeper 是 yahoo 公司使用 java 语言开发的,是 Hadoop 项目中的子项目,基于 Google 的 Chubby 的开源实现,在 Hadoop,Hbase,Kafka 等技术中充当核心组件的角色。

它的设计目标就是 将那些复杂并且容易出错的分布式一致性服务加以封装,构成高效且可靠的服务,并为用户提供一系列简单易用的接口

Zookeeper 是一个经典的 分布式数据一致性 解决方案,分布式应用程序可以基于它实现

  • 数据的发布和订阅
  • 负载均衡
  • 命名服务
  • 分布式协调与通知
  • 集群管理
  • 领导选举
  • 分布式锁
  • 分布式队列

zookeeper 一般都以 集群的方式 对外提供服务,一个集群包含多个节点,每个节点都对应一台 Zookeeper 服务器,所有的节点共同对外提供服务。具体包括以下五大特性:

  1. 顺序性
  2. 原子性
  3. 一致性
  4. 可靠性
  5. 实时性

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 知识点汇总的更多相关文章

  1. nginx几个知识点汇总

    WHY? 为什么用Nginx而不用LVS? 7点理由足以说明一切:1 .高并发连接: 官方测试能够支撑 5 万并发连接,在实际生产环境中跑到 2 - 3 万并发连接数.?2 .内存消耗少: 在 3 万 ...

  2. python全栈开发 * 10知识点汇总 * 180612

    10 函数进阶 知识点汇总 一.动态参数 形参的第三种1.动态接收位置传参 表达:*args (在参数位置编写 * 表⽰接收任意内容) (1)动态位置参数def eat(*args): print(a ...

  3. 清华大学OS操作系统实验lab1练习知识点汇总

    lab1知识点汇总 还是有很多问题,但是我觉得我需要在查看更多资料后回来再理解,学这个也学了一周了,看了大量的资料...还是它们自己的80386手册和lab的指导手册觉得最准确,现在我就把这部分知识做 ...

  4. c++ 函数知识点汇总

    c++ 函数知识点汇总 swap函数 交换两个数组元素 比如 swap(a[i],a[j]); 就是交换a[i] 和 a[j] 的值 strcpy() 复制一个数组元素的值到另一个数组元素里 strc ...

  5. 前端开发 JavaScript 干货知识点汇总

    很多初学的朋友经常问我,前端JavaScript都需要学习哪些东西呀?哪些是JavaScript的重点知识啊? 其实做前端开发工程师,所有的知识点都是我们学习必备的东西,只有扎实的技术基础才是高薪的关 ...

  6. BBS项目知识点汇总

    目录 bbs项目知识点汇总 一. JavaScript 1 替换头像 2 form表单拿数据 3 form组件error信息渲染 4 添加html代码 5 聚焦操作 二 . html在线编辑器 三 . ...

  7. Java面试知识点汇总

    Java面试知识点汇总 置顶 2019年05月07日 15:36:18 温柔的谢世杰 阅读数 21623 文章标签: 面经java 更多 分类专栏: java 面试 Java面试知识汇总   版权声明 ...

  8. 离散数学 II(最全面的知识点汇总)

    离散数学 II(知识点汇总) 目录 离散数学 II(知识点汇总) 代数系统 代数系统定义 例子 二元运算定义 运算及其性质 二元运算的性质 封闭性 可交换性 可结合性 可分配性 吸收律 等幂性 消去律 ...

  9. 我要进大厂之大数据ZooKeeper知识点(2)

    01 我们一起学大数据 接下来是大数据ZooKeeper的比较偏架构的部分,会有一点难度,老刘也花了好长时间理解和背下来,希望对想学大数据的同学有帮助,也特别希望能够得到大佬的批评和指点. 02 知识 ...

随机推荐

  1. 【转】TOP10美国虚拟主机/网站空间推荐

    原文:http://www.laozuo.org 不同的站长用户需要不同的主机产品,并不是所有的站长, 所有的网站都想放置在VPS服务器中的.虚拟主机也有虚拟主机的方便和优势,下面为老左精选的10个比 ...

  2. django admin编辑被外键关联的主表时支持显示字表记录

    假设有模型 class A(models.Model): name = models.CharField() class B(models.Model): name = models.CharFiel ...

  3. 基于alpine用dockerfile创建的ssh镜像

    1.下载alpine镜像 [root@docker43 ~]# docker pull alpine Using default tag: latest Trying to pull reposito ...

  4. JIRA服务器搭建

    JJIRA服务器搭建 http://wiki.csdn.net/display/CSDN/Atlassian CSDN国内代理: http://atlassian.csdn.net/m/btc/atl ...

  5. asp.net core中遇到需要自定义数据包解密方法的时候

    最近将公司的项目用.netcore重写, 服务的http外部接口部分收发消息是DES加解密的, 那么在asp.net core mvc的action处理之前需要加入解密这个步骤. 我第一想到的是用fi ...

  6. python中大于0的元素全部转化为1,小于0的元素全部转化为0的代码

    [code] """ 大于0的元素全部转化为1 """ np_arr = np.array([[1 ,2, 3, 4]]) print(&q ...

  7. asp.net调用js方法

    C#前台js调用后台代码 前台js <script type="text/javascript" language="javascript"> fu ...

  8. Andrew Ng机器学习课程笔记(六)之 机器学习系统的设计

    Andrew Ng机器学习课程笔记(六)之 机器学习系统的设计 版权声明:本文为博主原创文章,转载请指明转载地址 http://www.cnblogs.com/fydeblog/p/7392408.h ...

  9. JavaScript 经典笔记

    JavaScript 是弱类型的语言,所以编译器不能检测出类型错误. JavaScript 依赖于全局变量来进行链接.所有编译单元的所有顶级变量被撮合到一个被称为全局对象(the global obj ...

  10. Spring AOP切面变成——创建增强类

    说明 Spring使用增强类定义横向逻辑,同时Spring只支持方法连接点,增量类还包含在方法的哪一点添加横切代码的方位信息.所以增强既包含横向逻辑,又包含部分连接点的信息. 类型 按着增强在目标类方 ...