1.1 什么 zookeeper
Zookeeper是一种分布式协调服务,用于管理大型主机。在分布式环境中协调和管理服务式环境中协调和管理服务是一个复杂的过程。Zookeeper通过简单的架构和API解决了这个问题。Zookeeper允许开发人员专注于核心应用程序逻辑,而不必担心应用程序的分布式特性。
1.2 Zookeeper的应用场景
- 分布式协调组件
在 分布式系统 中,需要有zookeeper作为分布式协调组件,协调分布式系统中的状态。
- 分布式锁
zk在实现分布式锁上,可以做到强一致性(顺序一致性)。
- 无状态化实现

2 搭建Zookeeper服务器
下载地址:
2.1 zoo.fg 配置文件说明
tar -zxvf apache -zookeeper-3.7.1-bin.tar.gz
# zookeeper时间配置的基本单位
tickTime=2000
# 允许follower初始化连接到leader最大时长,它表示tickTime时间倍数 即:initLimit*tickTime
initLimit=10
# 允许follower与leader数据同步最大时长,它表示tickTime时间倍数
syncLimit=5
# zookeeper数据存储目录及日志保存(如果没有知名dataLogDir, 则日志也保存在这个文件中)
dataDir=/usr/local/zookeeper/zkdata
#dataLogDir=/usr/local/zookeeper/zkdata
# 对客户端提供的端口号
clientPort=2181
# 单位客户端与zookeeper最大并发连接数
maxClientCnxns=60
# 保存的数据快照数量,之外的将会被清除
autopurge.snapRetainCount=3
# 自动触发清除任务时间间隔,小时为单位。默认为0,表示不自动清除
autopurge.purgeInterval=1
2.2 zookeeper服务器的操作命令
- 重命名 conf 中 zoo_sample.cfg 为 zoo.cfg
cp zoo_sample.cfg zoo.cfg
- 启动zk服务器
cd /usr/local/zookeeper/apache-zookeeper-3.7.1-bin
bin/zkServer.sh start conf/zoo.cfg
- 查看zk服务器状态
bin/zkServer.sh status
- 停止服务器
bin/zkServer.sh stop conf/zoo.cfg
Cli连接指定服务器
bin/zkCli.sh
3 Zookeeper内部的数据模型
3.1 zk是如何保存数据的
zk中数据是保存在节点上的,节点就是znode,多个znode支架构成一棵树的目录结构。
创建节点
create /test1
create /test1/sub1
ls /
ls /test1
创建节点 test2 ,并放入数据 abc
create /test2 abc
获取数据
get /test2
3.2 zk中znode结构
- data:保存数据
- acl:权限(定义什么用户能操作此节点,并且进行怎样的操作)
- c:create创建权限,允许该节点下创建子节点
- w:write更新权限,允许更新该节点的数据
- r:read读取权限,允许读取该节点的内容以及子节点的列表信息
- d:delete删除权限,允许删除该及诶单的子节点
- a:admin管理者权限,允许对该节点进行alc权限设置
- stat:描述当前znode的元数据
- child:当前节点的子节点
3.3 zk中节点znode的类型
- 持久节点:创建出的节点,在会话结束后依然存在。
create /test5
- 持久序号节点:创建出的节点,根据先后顺序,会在节点之后带上一个数值,越后执行数值越大,适用于分布式锁的应用场景-单调递增
create -s /test5
- 临时节点:临时节点是在会话结束后,自动被删除的,通过这个特性,zk可以实现服务注册与发现的效果。
create -e /test5
临时节点维持 心跳 :
3.4 zk数据的持久化

zk的数据是运行在内存中,zk提供了2中持久化机制:
- 事务日志:zk把执行的命令以日志形式保存在dataLogDir指定的路径中的文件中(如果没有指定dataLogDir,则按dataDir指定的路径)、
- 数据快照:zk会在一定的时间间隔内做一次内存数据的快照,把该时刻的内存数据保存在快照文件中。
zk通过两种的时间间隔内做一次内存数据的快照,把该时刻的内存数据保存在快照文件中。
4 Zookeeper客户端(zkCli)的使用
4.1 多节点类型创建
1、创建持久节点
create /test5
2、 创建持久 序号 节点 (并发很严重时)
create -s /test5
3、创建临时节点
- 临时节点是在会话结束后,自动被删除的,
create -e /test5
- 实现了服务注册与发现
4、创建临时序号节点
- 跟序号节点相同,适用于临时的分布式锁。
create -e -s /test6
5、Container节点(3.5.3版本新增)
- Container容器节点中没有任何子节点,该容器节点会被zk定期删除(60s)。
# 创建容器节点
create -c /mycontainer
# 创建子节点
create /mycontainer/sub1
create /mycontainer/sub2
# 删除子节点
delete /mycontainer/sub1
delete /mycontainer/sub2
6、TTL节点
- 可以指定节点的到期时间,到期后被zk定时删除。只能通过系统配置 zookeeper.extendTypesEnabled=true
4.2 查询节点
get -s /test2
- cZxid:创建节点事务ID
- mZxid:修改节点的事务ID
- pZxid:添加和删除子节点的事务ID
- ctime :节点创建的时间
- mtime:节点最近修改的时间
- dataVersion:节点内存数据版本,每更新一次数据,版本会+1
- aclVersion:此节点权限版本
- ephemeralOwner:如果当前节点是临时节点,该值是当前节点所有者的的session id。如果及诶单不是临时节点,则该值为0
- dataLength:节点内数据的长度
- numChildren:该节点的子节点个数
4.3 删除
delete /test1
deleteall /test1
按照数据版本号删除(乐观锁删除)
delete -v 版本 /节点
delete -v 1 /test2
4.4 权限
- 注册当前会话的账号和密码
addauth digest charles:123456
- 创建节点并设置权限
create /test-node abc auth:charles:123456:cdwra
- 在另一个会话中必须使用账号密码,才能拥有该节点的权限
其他会话读取,权限不足提醒

5 Curator 客户端的使用
官网:
Curator是Netflix公司开源的一套zookeeper客户端框架,Curator是对Zookeeper支持最好的客户端框架。Curator封装了大部分Zookeeper的功能,比如Leader选举、分布式锁等,减少了技术人员在使用Zookeeper时的底层细节开发的工作。
5.1 引入Curator
引入依赖
<!-- -->
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>5.2.0</version>
</dependency>
<!-- -->
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<version>5.2.0</version>
</dependency>
<!-- -->
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.7.1</version>
</dependency>
8 集群搭建
8.1 伪分布式
1、在 /usr/local/zookeeper 中创建zk1~zk4,然后 新建 myid 文件
echo 1 > ./zk1/myid
echo 2 > ./zk2/myid
echo 3 > ./zk3/myid
echo 4 > ./zk4/myid
2、编写zoo.cfg文件
伪分布式(4个)
# The number of milliseconds of each tick
tickTime=2000
# The number of ticks that the initial
initLimit=10
syncLimit=5
# 修改为对应的zk1、zk2、zk3、zk4
dataDir=/usr/local/zookeeper/zkdata/zk1
# 修改为对应的端口 2181、2182、2183、2184
clientPort=2181
# 2001为集群通信端口,3001为集群选举端口, observer 表示不参数集群选举
server.1=192.168.56.20:2001:3001
server.2=192.168.56.20:2002:3002
server.3=192.168.56.20:2003:2003
# server.4=192.168.56.23=2004:2004:observer
3、启动3台Zookeeper
./bin/zkServer.sh start ./conf/zoo1.cfg
./bin/zkServer.sh start ./conf/zoo2.cfg
./bin/zkServer.sh start ./conf/zoo3.cfg
8.2 分布式
1、创建数据存放目录
mkdir /usr/local/zookeeper/zkdata
2、修改 zoo.cfg
cp zoo_sample.cfg zoo.cfg
# The number of milliseconds of each tick
tickTime=10000
# The number of ticks that the initial
initLimit=10
syncLimit=5
# 修改为对应的zk1、zk2、zk3、zk4
dataDir=/usr/local/zookeeper/zkdata
# 修改为对应的端口 2181、2182、2183、2184
clientPort=2181
server.1=192.168.56.20:2888:3888
server.2=192.168.56.21:2888:3888
server.3=192.168.56.22:2888:3888
# server.4=192.168.56.23=:2888:3888:observer
3、将zookeeper目录发送到其他节点
scp -r /usr/local/zookeeper/ 192.168.56.21:/usr/local
scp -r /usr/local/zookeeper/ 192.168.56.22:/usr/local
4、分别修改三台机器 myid
echo 1 > /usr/local/zookeeper/zkdata/myid
echo 2 > /usr/local/zookeeper/zkdata/myid
echo 3 > /usr/local/zookeeper/zkdata/myid
5、编写操作 zookeeper 集群的脚本
cd /usr/local/zookeeper/bin
vim zk.sh
# 添加如下内容
#!/bin/bash
case $1 in
"start"){
for i in master slave1 slave2
do
echo -------------------------------- $i zookeeper 启动 ---------------------------
ssh $i "/usr/local/zookeeper/apache-zookeeper-3.7.1-bin/bin/zkServer.sh start"
done
}
;;
"stop"){
for i in master slave1 slave2
do
echo -------------------------------- $i zookeeper 停止 ---------------------------
ssh $i "/usr/local/zookeeper/apache-zookeeper-3.7.1-bin/bin/zkServer.sh stop"
done
}
;;
"status"){
for i in master slave1 slave2
do
echo -------------------------------- $i zookeeper 状态 ---------------------------
ssh $i "/usr/local/zookeeper/apache-zookeeper-3.7.1-bin/bin/zkServer.sh status"
done
}
;;
esac
# 保存退出后,修改zk.sh脚本执行权限
chmod +x ./zk.sh
脚本说明:
# 启动集群命令
./zk.sh start
# 停止集群命令
./zk.sh stop
# 查看集群状态命令
./zk.sh status
6、启动集群
/usr/local/zookeeper/bin/zk.sh start
或
cd /usr/local/zookeeper/apache-zookeeper-3.7.1-bin
./bin/zkServer.sh start ./conf/zoo.cfg



工具连接
bin/zkCli.sh