它是一个针对大型分布式应用程序的分布式协调服务,通过共享的分层名称空间相互协调,该命名空间的组织方式类似于文件系统,由ZNode 节点组成,ZooKeeper数据保留在内存中。
ZK 公开了一组简单的原语,分布式应用程序可以基于这些原语实现分布式同步、配置维护及分布式节点统一命名等服务。
分布式协调,高性能,高扩展性,高可用性,严格的有序访问,快速自我修复,Zookeeper 特点:
ZK 有2种运行状态:
可用状态
不可用状态
不可用状态恢复到可用状态要恢复够快,zk选择新leader的时间不到200毫秒
客户端连接时会创建session,且 ZK 是统一视图,如果创建时连接的 ZK 服务器挂了,切换到另一台,同样有效。
ZK 有四种类型的znode:
PERSISTENT - 持久化目录节点
客户端与zookeeper断开连接后,该节点依旧存在
PERSISTENT_SEQUENTIAL - 持久化顺序编号目录节点
客户端与zookeeper断开连接后,该节点依旧存在,只是Zookeeper给该节点名称进行顺序编号
EPHEMERAL - 临时目录节点
客户端与zookeeper断开连接后,该节点被删除
EPHEMERAL_SEQUENTIAL - 临时顺序编号目录节点
客户端与zookeeper断开连接后,该节点被删除,只是Zookeeper给该节点名称进行顺序编号
ZK 三种集群节点角色
leader: 支持读写
follower: 只读且参与投票
observer: 只读不参与投票,可以增加性能,减少内部监控损耗
1.1 下载 ZooKeeper,在 Apache 官网找到对就的版本,官网地址:https://zookeeper.apache.org
现在规划4台机,分别是 n71,n72,n73,n74
1.2 解压安装
$ tar -zxvf apache-zookeeper-3.6.1-bin.tar.gz -C /usr/local/
$ cd /usr/local/
$ ln -s apache-zookeeper-3.5.5-bin zookeeper
$ cd /usr/local/zookeeper/conf
1.3 配置 zoo.conf
$ cp zoo_sample.cfg zoo.cfg
$ vi zoo.cfg
# 修改dataDir, 并在dataDir目录下创建myid文件,里面输入一个数字
dataDir=/var/zookeeper
# 添加server
server.1=n71:2888:3888
server.2=n72:2888:3888
server.3=n73:2888:3888
server.4=n74:2888:3888:observer
不能有相同的 id 的节点,需要确保每个节点的 myid 文件中 id值不同
每一行 “server.id=host:port:port” 中的 id 值,需要与对应节点的数据目录下的 myid 文件中的 id 值保持一致
每个配置文件都需要配置全部的节点信息。不仅仅是配置自己的那份,还需要配置所有节点的 id、ip、端口
在每一行 “server.id=host:port:port” 中,需要配置两个端口。前一个端口(2888)用于节点之间的通信,后一个端口(3888)用于选举主节点。
端口2888: 选举出来后leader会打开2888端口,follower节点连接leader的2888端口进行通信
端口3888: 如果没有leader或leader挂了后,follower节点通过3888接口通信投票
ZK 节点除了leader和follow模式之外,还有第三种模式:observer模式,observer 节点没有投票权,即它不参与选举和写请求的投票。
使用observer模式的一个主要的理由就是对读请求进行扩展。通过增加更多的observer,可以接收更多的请求的流量,却不会牺牲写操作的吞吐量。
使用observer的另一个原因是跨数据中心部署。把participant分散到多个数据中心可能会极大拖慢系统,因为数据中心之间的网络的延迟。使用observer的话,更新操作都在一个单独的数据中心来处理,并发送到其他数据中心,让其他数据中心的client消费数据。
observer的使用并无法完全消除数据中心之间的网络延迟,因为observer不得不把更新请求转发到另一个数据中心的 leader,并处理INFORM消息,网络速度极慢的话也会有影响,它的优势是为本地读请求提供快速响应。
1.4 将配置通过 scp 分发到其它几台机
$ scp zoo.cfg root@n72:`pwd`/
$ scp zoo.cfg root@n73:`pwd`/
$ scp zoo.cfg root@n74:`pwd`/
1.5 分别为每个节点创建 myid
$ mkdir /var/zookeeper
$ vi /var/zookeeper/myid
1.6 分别为每个节点配置 ZK 环境变量
$ vi /etc/profile
# 在最后添加 ZK 环境变量,这里的 Java & Redis 是之前已经装好的。
# ZooKeeper 运行在 JVM 中,所以需要先安装 JDK。
JAVA_HOME=/usr/local/jdk
ZOOKEEPER_HOME=/usr/local/zookeeper
PATH=$JAVA_HOME/bin:$PATH:$ZOOKEEPER_HOME/bin
$ . /etc/profile
1.7 ZooKeeper 其它配置
# 配置单元时间,是 ZooKeeper 的时间计算单元,其他的时间间隔都是使用 tickTime 的倍数来表示的。默认是 3000 毫秒
tickTime=2000
# 初使建立连接等待时间: tickTime*initLimit = 20秒
initLimit=10
# 心跳最大延迟周期,该参数用于配置 Leader 节点和 Follow 节点之间进行心跳检测的最大延迟时间。Leader 节点会通过心跳检测来确定 Follower 节点是否存活。在 tickTime * syncLimit 时间内无法获取到 Follower 节点的心跳检测响应,那么就会认为该 Follower 节点已经脱离了和 Leader 的同步。
syncLimit=5
# 快照数据存放目录,修改 dataDir, 并在 dataDir目录下创建 myid 文件,里面输入一个数字
dataDir=/var/zookeeper
# 客户端连接端口
clientPort=2181
# 允许最大客户连接数
maxClientCnxns=60
1.8 启动
zkServer.sh help 查看启用服务命令详情
$ zkServer.sh help
/usr/local/jdk/bin/java
ZooKeeper JMX enabled by default
Using config: /usr/local/zookeeper/bin/../conf/zoo.cfg
Usage: /usr/local/zookeeper/bin/zkServer.sh [--config <conf-dir>] {
start|start-foreground|stop|version|restart|status|print-cmd}
zkServer.sh help 可以显示zkServer.sh 可用的参数
zkServer.sh status 查看不前zk 服务状态
zkServer.sh start 启动服务
zkServer.sh start-foreground 以前台方式启动服务,log 会打印在控制台界面
zkCli.sh 连接到当前机器的 zk 客户端,连接后输入help, 可以查看所有命令
$ zkCli.sh -server 127.0.0.1:2181
[zk: localhost:2181(CONNECTED) 3] help
ZooKeeper -server host:port -client-configuration properties-file cmd args
addWatch [-m mode] path # optional mode is one of [PERSISTENT, PERSISTENT_RECURSIVE] - default is PERSISTENT_RECURSIVE
addauth scheme auth
close
config [-c] [-w] [-s]
connect host:port
create [-s] [-e] [-c] [-t ttl] path [data] [acl]
delete [-v version] path
deleteall path [-b batch size]
delquota [-n|-b] path
get [-s] [-w] path
getAcl [-s] path
getAllChildrenNumber path
getEphemerals path
history
listquota path
ls [-s] [-w] [-R] path
printwatches on|off
quit
reconfig [-s] [-v version] [[-file path] | [-members serverID=host:port1:port2;port3[,...]*]] | [-add serverId=host:port1:port2;port3[,...]]* [-remove serverId[,...]*]
redo cmdno
removewatches path [-c|-d|-a] [-l]
set [-s] [-v version] path data
setAcl [-s] [-v version] [-R] path acl
setquota -n|-b val path
stat [-w] path
sync path
version
Command not found: Command not found help
# 现在新版本输入任意不存在的命令都会打印信息,并提示“Command not found” *·*
启动后可以通过 netstat -natp | egrep '(2888|3888)'
查看各节点间的连接通信
egrep: 支持正则表达式
$ netstat -natp | egrep '(2888|3888)'
tcp6 0 0 192.168.79.152:3888 :::* LISTEN 1196/java
tcp6 0 0 192.168.79.152:3888 192.168.79.154:55250 ESTABLISHED 1196/java
tcp6 0 0 192.168.79.152:45026 192.168.79.154:2888 ESTABLISHED 1196/java
tcp6 0 0 192.168.79.152:37560 192.168.79.151:3888 ESTABLISHED 1196/java
tcp6 0 0 192.168.79.152:3888 192.168.79.153:35700 ESTABLISHED 1196/java
进入到/etc/rc.d/init.d目录下,新建一个zookeeper脚本
$ cd /etc/rc.d/init.d/
$ touch zookeeper
$ chmod +x zookeeper
编辑 zookeeper 在脚本中输入如下内容
#!/bin/bash
#chkconfig:2345 20 90
#description:zookeeper
#processname:zookeeper
export JAVA_HOME=/usr/local/jdk
case $1 in
start) su root /usr/local/zookeeper/bin/zkServer.sh start;;
stop) su root /usr/local/zookeeper/bin/zkServer.sh stop;;
status) su root /usr/local/zookeeper/bin/zkServer.sh status;;
restart) su /usr/local/zookeeper/bin/zkServer.sh restart;;
*) echo "require start|stop|status|restart" ;;
esac
使用service 管理 zookeeper
service zookeeper start|stop|status|restart
添加到开机启动
$ chkconfig --add zookeeper
create [-s] [-e] [-c] [-t ttl] path [data] [acl]
:在树中的某个位置创建一个节点
-e:EPHEMERAL 创建一个临时目录节点,表示是当前session 有效的。session断开就会被失效
-s:SEQUENTIAL 顺序编号目录节点,文件名会添加序列号后缀,可以避免并发下的覆盖,实现分布式锁功能。
[zk: localhost:2181(CONNECTED) 1] create -e -s /abc
Created /abc0000000002
[zk: localhost:2181(CONNECTED) 2] ls /
[aaa, abc0000000002, zookeeper]
# 退出后重登录,再次查看 ephemeral 节点消失了
[zk: localhost:2181(CONNECTED) 1] ls /
[aaa, zookeeper]
ls [-s] [-w] [-R] path
列出一个节点下的子节点
-s:显示 stat 信息
-R:递归显示子目录信息
-w:对目录添加一个 watch 事件,如果子节点有变更,当前界面可以收到通知。只能 watch 一次。
[zk: localhost:2181(CONNECTED) 2] ls /
[aaa, zookeeper]
[zk: localhost:2181(CONNECTED) 25] ls -R /
/
/aaa
/zookeeper
/aaa/bbb
/aaa/bbb/ccc
/zookeeper/config
/zookeeper/quota
delete [-v version] path
:删除节点
如果该节点存在子节点,则删除失败
deleteall path [-b batch size]
删除节点
如果该节点存在子节点,将会一起删除
set [-s] [-v version] path data
对某个存在的节点进行设置值
-s:显示 stat 信息
[zk: localhost:2181(CONNECTED) 8] set /aaa abctest
get [-s] [-w] path
查看某个节点的数据
-s:显示 stat 信息
[zk: localhost:2181(CONNECTED) 9] get /aaa
abctest
stat [-w] path
查看节点状态,显示一个节点的 stat/metadata
[zk: localhost:2181(CONNECTED) 12] stat /aaa
# 创建时的事务ID,0x 表示16进制,代表每位为4个字节,前面如果为0可以显示省略。
# 0x0000000200000002 = 0x200000002
# 前32位表示leader纪元,第几个leader 时创建的。
cZxid = 0x500000021
# 创建时间
ctime = Thu Aug 20 00:48:52 PDT 2020
# 修改时的事务ID
mZxid = 0x500000022
# 修改时间
mtime = Thu Aug 20 00:48:57 PDT 2020
# 当前节点下,创建的最后子节点ID号
pZxid = 0x500000021
# 子节点版本号,子节点每次修改,该版本号就加1
cversion = 0
# 数据版本号,数据每次修改,该版本号就加1
dataVersion = 1
# 权限版本号,权限每次修改,该版本号就加1
aclVersion = 0
# 如果是ephemeral临时节点,这里会显示创建它的sesssion id
ephemeralOwner = 0x0
# 内容所占字节数,zk 是二进制安全的,客户端传入什么字节,就存放什么字节,不会进行转换。读取时直接返回字节内容
dataLength = 7
# 子节点的数量
numChildren = 0
close
关闭连接
connect host:port
重新连接
quit
退出客户端窗口
history
查看当前连接执行的11条命令
sync path
从 Leader 同步某个节点的数据 (Asynchronous sync)
官网地址:https://zookeeper.apache.org
安装文档参考:https://zookeeper.apache.org/doc/current/zookeeperStarted.html
客户端命令文档参考:https://zookeeper.apache.org/doc/current/zookeeperCLI.html