概述
说点正确的废话
zookeeper是一个分布式协调框架,是Apache Hadoop 的一个子项目,它主要是用来解决分布式应用中经常遇到的一些数据管理问题,如:统一命名服务、状态同步服务、集群管理、分布式应用配置项的管理等。
ZK由JAVA编写,支持JAVA 和C两种语言的客户端。
ZK产生的背景
通常情况下,单个物理节点很容易达到性能,计算或者容量的瓶颈,所以这个时候就需要多个物理节点来共同完成某项任务,一个分布式系统的本质是分布在不同网络或计算机上的程序组件,彼此通过信息传递来协同工作的系统,而Zookeeper正是一个分布式应用协调框架,在分布式系统架构中有广泛的应用场景。
项目从单体到分布式转变之后,将会产生多个节点之间协同的问题
- 每天的定时任务由谁哪个节点来执行
- RPC调用时的服务发现
- 如何保证并发请求的幂等
- …
这些问题可以统一归纳为多节点协调问题,如果靠节点自身进行协调这是非常不可靠的,性能上也不可取。必须由一个独立的服务做协调工作,它必须可靠,而且保证性能。
安装
JDK依赖
Java编写,依赖JDK, JDK Version >=8
下载
官网下载: https://zookeeper.apache.org/releases.html#download
当然了,国内也有镜像可以下载,比如
3.5.8 版本
代码语言:javascript复制[root@localhost ~]# wget https://mirrors.tuna.tsinghua.edu.cn/apache/zookeeper/zookeeper-3.5.8/apache-zookeeper-3.5.8-bin.tar.gz
3.6.2 版本
代码语言:javascript复制[root@localhost ~]# wget https://mirrors.tuna.tsinghua.edu.cn/apache/zookeeper/zookeeper-3.6.2/apache-zookeeper-3.6.2-bin.tar.gz
这里我们选用3.5.8的版本
解压
代码语言:javascript复制[root@localhost ~]# tar -xvzf apache-zookeeper-3.5.8-bin.tar.gz
修改配置文件
代码语言:javascript复制cd {zookeeper_home}/conf # 按实际路径调整
cp zoo_sample.cfg zoo.cfg
启动 / 停止
代码语言:javascript复制 {zookeeper_home}/bin/zkServer.sh # 按实际路径调整,查看启动支持哪些参数
[root@localhost bin]# ./zkServer.sh
/usr/bin/java
ZooKeeper JMX enabled by default
Using config: /root/apache-zookeeper-3.5.8-bin/bin/../conf/zoo.cfg
Usage: ./zkServer.sh [--config <conf-dir>] {start|start-foreground|stop|restart|status|print-cmd}
[root@localhost bin]#
启动,采用默认的配置文件
代码语言:javascript复制[root@localhost bin]# ./zkServer.sh start
/usr/bin/java
ZooKeeper JMX enabled by default
Using config: /root/apache-zookeeper-3.5.8-bin/bin/../conf/zoo.cfg
Starting zookeeper ... STARTED
[root@localhost bin]#
停止
代码语言:javascript复制[root@localhost bin]# ./zkServer.sh stop
/usr/bin/java
ZooKeeper JMX enabled by default
Using config: /root/apache-zookeeper-3.5.8-bin/bin/../conf/zoo.cfg
Stopping zookeeper ...
STOPPED
[root@localhost bin]#
也可以指定配置文件,不指定的话默认使用 conf/zoo.cfg
代码语言:javascript复制[root@localhost bin]# ./zkServer.sh start ../conf/zoo.cfg
连接服务器
代码语言:javascript复制bin/zkCli.sh ‐server ip:port
例子
代码语言:javascript复制[root@localhost bin]# ./zkCli.sh -server 192.168.126.129:2181
/usr/bin/java
Connecting to 192.168.126.129:2181
2020-11-15 23:43:05,472 [myid:] - INFO [main:Environment@109] - Client environment:zookeeper.version=3.5.8-f439ca583e70862c3068a1f2a7d4d068eec33315, built on 05/04/2020 15:07 GMT
........
........
........
Welcome to ZooKeeper!
........
........
........
WATCHER::
WatchedEvent state:SyncConnected type:None path:null
[zk: 192.168.126.129:2181(CONNECTED) 0]
配置文件说明
代码语言:javascript复制# zookeeper时间配置中的基本单位 (毫秒)
tickTime=2000
# 允许follower初始化连接到leader最大时长,它表示tickTime时间倍数 即:initLimit*tickTime
initLimit=10
# 允许follower与leader数据同步最大时长,它表示tickTime时间倍数
syncLimit=5
#zookeper 数据存储目录
dataDir=/tmp/zookeeper
#对客户端提供的端口号
clientPort=2181
#单个客户端与zookeeper最大并发连接数
maxClientCnxns=60
# 保存的数据快照数量,之外的将会被清除
autopurge.snapRetainCount=3
#自动触发清除任务时间间隔,小时为单位。默认为0,表示不自动清除。
autopurge.purgeInterval=1
ZK 核心概念 (文件系统数据结构 监听通知机制)
可以先把Zookeeper 理解为 是一个用于存储少量数据的基于内存的数据库,主要有如下两个核心的概念:文件系统数据结构 监听通知机制
文件系统数据结构
Zookeeper维护一个类似文件系统的数据结构
每个子目录项都被称作为 znode(目录节点),和文件系统类似,可以自由的增加、删除znode,在一个znode下增加、删除子znode。
6种Node类型
- PERSISTENT-持久化目录节点
客户端与zookeeper断开连接后,该节点依旧存在,只要不手动删除该节点,永远存在
- PERSISTENT_SEQUENTIAL-持久化顺序编号目录节点
客户端与zookeeper断开连接后,该节点依旧存在,只是Zookeeper给该节点名称进行顺序编号 ,非常适合用于分布式锁、分布式选举等场景
- EPHEMERAL-临时目录节点
客户端与zookeeper断开连接后,该节点被删除 适用于心跳,服务发现等场景。
- EPHEMERAL_SEQUENTIAL-临时顺序编号目录节点
客户端与zookeeper断开连接后,该节点被删除,只是Zookeeper给该节点名称进行顺序编号
- Container 节点
3.5.3 版本新增,如果Container节点下面没有子节点,则Container节点在未来会被Zookeeper自动清除,定时任务默认60s 检查一次
- TTL 节点 (Time To Life)
默认禁用,只能通过系统配置 zookeeper.extendedTypesEnabled=true 开启,不稳定
监听通知机制
客户端注册监听它关心的任意节点,或者目录节点及递归子目录节点
- 如果注册的是对某个节点的监听,则当这个节点被删除,或者被修改时,对应的客户端将被通知
- 如果注册的是对某个目录的监听,则当这个目录有子节点被创建,或者有子节点被删除,对应的客户端将被通知
- 如果注册的是对某个目录的递归子节点进行监听,则当这个目录下面的任意子节点有目录结构的变化(有子节点被创建,或被删除)或者根节点有数据变化时,对应的客户端将被通知。
注意:
- 所有的通知都是一次性的,及无论是对节点还是对目录进行的监听,一旦触发,对应的监听即被移除。
- 递归子节点,监听是对所有子节点的,所以,每个子节点下面的事件同样只会被触发一次。
ZK的应用场景
- 分布式配置中心
- 分布式注册中心
- 分布式锁
- 分布式队列
- 集群选举
- 分布式屏障
- 发布/订阅
- …