Zookeeper 入门
大约 7 分钟
一、概述
Zookeeper 是一个开源的分布式的,的Apache 项目
Zookeeper从设计模式角度来理解:是一个基于观察者模式设计的分布式服务管理框架,它,然后接受观察者的注册,一旦这些数据的状态发生变化,Zookeeper就将做出相应的反应
1 Zookeeper特点
- 一个领导者(Leader),多个跟随者(Follower)组成的集群。
- 集群中只要有节点存活,Zookeeper集群就能正常服务。所以Zookeeper适合安装奇数台服务器
- ,每个Server保存一份相同的数据副本,Client无论连接到哪个Server,数据都是一致的。
- 更新请求顺序执行,来自同一个Client的更新请求按其发送顺序依次执行
- ,一次数据更新要么成功,要么失败。
- ,在一定时间范围内,Client能读到最新数据
2 Zookeeper数据结构
ZooKeeper数据模型的结构与 Unix 文件系统很类似,整体上可以看作是一棵树,每个节点称做一个 ZNode。每一个 ZNode 默认能够存储 1MB 的数据,每个 ZNode 都可以通过其路径唯一标识。

3 应用场景
3.1 统一配置服务
- 分布式环境下,配置文件同步非常常见。
- 一般要求一个集群中,所有节点的配置信息是一致的。
- 对配置文件修改后,希望能够快速同步到各个节点上。
- 配置管理可交由ZooKeeper实现。
- 可将配置信息写入ZooKeeper上的一个Znode。
- 各个客户端服务器监听这个Znode。
- 一旦Znode中的数据被修改,ZooKeeper将通知各个客户端服务器。
3.2 统一集群管理
- 分布式环境中,实时掌握每个节点的状态是必要的,可根据节点实时状态做出一些调整。
- ZooKeeper可以实现实时监控节点状态变化。
- 可将节点信息写入ZooKeeper上的一个ZNode。
- 监听这个ZNode可获取它的实时状态变化。
3.3 服务器动态上下线
客户端能实时洞察到服务器上下线的变化
3.4 软负载均衡
在Zookeeper中记录每台服务器的访问数,让访问数最少的服务器去处理最新的客户端请求
二、下载、安装
1 安装jdk环境
2 安装Zookeeper
下载
# 创建工作目录 mkdir -p /data/zookeeper cd /data/zookeeper # 下载 wget https://archive.apache.org/dist/zookeeper/zookeeper-3.5.7/apache-zookeeper-3.5.7-bin.tar.gz # 解压 tar -zxvf apache-zookeeper-3.5.7-bin.tar.gz # 改名 mv apache-zookeeper-3.5.7 zookeeper
配置
# 拷贝原始配置文件 cd /data/zookeeper/conf cp zoo_sample.cfg zoo.cfg # 创建zookeeper数据存放目录 mkdir -p /data/zookeeper/data vim /data/zookeeper/conf/zoo.cfg # 修改数据保存目录 # dataDir=/data/zookeeper/data
3 启动
3.1 启动服务端
cd /data/zookeeper/zookeeper/
./bin/zkServer.sh start
# 查看状态
./bin/zkServer.sh status
# 关闭服务端
# ./bin/zkServer.sh stop
3.2 启动客户端
./bin/zkCli.sh
# 退出客服端
# quit
3.3 配置参数解读
- tickTime:通讯心跳时间
- initLimit:初始通讯实现(Leader和Follower)
- syncLimie:同步通信实现(Leader和Follower)
- dataDir:保存Zookeeper数据的目录
- clientPort:端口
三、集群操作
1 启动集群
准备三台linux服务器
IP | 安装目录 | 存放数据目录 | myid |
---|---|---|---|
192.168.163.128 | /opt/zookeeper-3.5.7 | /opt/zookeeper-3.5.7/data | 3 |
192.168.163.127 | /opt/zookeeper-3.5.7 | /opt/zookeeper-3.5.7/data | 2 |
192.168.163.126 | /opt/zookeeper-3.5.7 | /opt/zookeeper-3.5.7/data | 1 |
添加myid文件(三台机器)
cd /opt/zookeeper-3.5.7/data
# 内容为上面表格myid列的内容
vim myid
修改配置(三台机器)
dataDir=/opt/zookeeper-3.5.7/data
# A myid里面配置的编号
# B 服务器ip
# C 是这个服务器 Follower 与集群中的 Leader 服务器交换信息的端口;
# D 万一集群中的 Leader 服务器挂了,需要一个端口来重新进行选举,选出一个新的Leader,而这个端口就是用来执行选举时服务器相互通信的端口。
# server.A=B:C:D
server.1=192.168.163.126:2888:3888
server.2=192.168.163.127:2888:3888
server.3=192.168.163.128:2888:3888
启动
# 三台都启动
/opt/zookeeper-3.5.7/bin/zkServer.sh start
# 查看状态
/opt/zookeeper-3.5.7/bin/zkServer.sh status
集群状态
IP | Model |
---|---|
192.168.163.126 | follower |
192.168.163.127 | leader |
192.168.163.128 | follower |
2 选举机制
第一次启动
- 192.168.163.126 启动,发起一次选举。服务器投自己一票。此时服务器1票数一票,不够半数以上LOOKING
- 192.168.163.127 启动,再发起一次选举。126和127分别投自己一票并交换选票信息:此时126发现127的myid比目前投票推举(126)的大,更改选票为推举服务器127。此时服务器127票数为2,126票数为0。127票数超半数,成为leader。服务器127更改状态为LEADING,服务器126更改状态为FOLLOWING。
- 192.168.163.128 启动,发起一次选举。此时服务器126,127经不是LOOKING状态,此时服务器128服从多数,更改选票信息为服务器128,并更改状态为FOLLOWING;
非第一次启动
在服务器运行期间无法与Leader保持连接,则会发起一次Leader选举。而当一台机器进入Leader选举流程时,当前集群也可能会处于以下两种状态:
- 集群中本来就已经存在一个Leader。 对于第一种已经存在Leader的情况,机器试图去选举Leader时,会被告知当前服务器的Leader信息,对于该机器来说,仅仅需要和Leader机器建立连接,并进行状态同步即可。
- 集群中确实不存在Leader,开始进行Leader选举。
:
名称 | 含义 |
---|---|
EPOCH | 每个Leader任期的代号。没有Leader时同一轮投票过程中的逻辑时钟值是相同的。每投完一次票这个数据就会增加 |
ZXID | 事务id,用来标识一次服务器状态的变更。在某一时刻,集群中的每台机器的ZXID值不一定完全一致,这和ZooKeeper服务器对于客户端“更新请求”的处理逻辑有关。 |
SID | 服务器ID。用来唯一标识一台ZooKeeper集群中的机器,每台机器不能重复,和myid一致。 |
- EPOCH大的胜出
- EPOCH相同,ZXID大的胜出
- ZXID相同,SID大的胜出
四、客服端节点操作
节点类型:
:客服端和服务器断开连接后,创建的节点不删除
:客服端和服务器断开连接后,创建的节点自动删除
1 创建节点
1.1 创建持久化节点
create /node "nodeval"
create /node/nodename "nodeval"
# 查看节点
ls /
ls /node
创建带有顺序标识的持久化节点,加上-s
参数
create -s /node_num1
create -s /node_num2
ls /
说明:创建znode时设置顺序标识,znode名称后会附加一个值,顺序号是一个单调递增的计数器,由父节点维护
注意:在分布式系统中,顺序号可以被用于为所有的事件进行全局排序,这样客户端可以通过顺序号推断事件的顺序
1.2 创建临时节点
加上-e
参数
create -e /node_tmp "tmp_value"
创建带有顺序标识的临时节点,加上-s
、-e
参数
create -s -e /tmp_num "tmp_num_value"
2 修改节点值
# set /node nodeval
set /node "12345678"
3 获取节点值
# get /node
get /node
4 获取节点状态的信息
get -s /node

- czxid:创建节点的事务zxid
- ctime:znode被创建的毫秒数
- mzxid:znode最后更新的事务id
- mtime:znode最后修改的毫秒数
- pZxid:znode最后更新的子节点zxid
- cversion:znode子节点变化号,znode子节点修改次数
- dataversion:znode数据变化号
- aclVersion:znode访问控制列表的变化号
- ephemeralOwner:如果是临时节点,这个znode拥有者的session id。如果不是临时节点则是0
- dataLength:znode的数据长度
- numChildren:znode的子节点数量
5 删除节点
delete
# 当节点含有子节点时无法删除 delete /node_child
deleteall
:删除节点及其子节点deleteall /node
6 监听节点变化
通过-w
参数来监听节点变化
# 监听节点值变化
get -w /node
# 监听节点操作
ls -w /node
# 在另外一台主机上操作之后,这个客服端会收到相应的通知
在另外一台主机上修改/node节点
# 重新赋值
set /node 12345
# 删除节点
delete /node