一、ZK介绍
Zookeeper是一个分布式协调框架,主要用来解决分布式场景下的数据一致性问题。ZK本质上是一个分布式的小文件存储系统,主要功能是文件系统 + 监听机制。
文件系统:ZK提供类似于文件系统的目录树方式的数据存储,并对树中的节点进行有效管理,不同于普通文件系统,ZK中的树节点称为ZNODE,且每个节点都可以存储数据。
监听机制:客户端会对关注的ZK节点或者节点数据在ZK服务器端进行注册,当这些节点、子节点、或者数据发生变化时,会主动通知客户端。注意服务器端只能通知客户端一次,如果需要继续监听,需要客户端重新注册。
二、ZK的安装
1、下载地址:https://zookeeper.apache.org/releases.html
2、解压压缩包
3、修改配置文件
配置文件各个参数的解释
4、启动ZK
bin/zkCli.sh -server ip:port
三、ZK客户端常用命令 以及可视化工具
可视化工具:ZooInspector
四、ZK数据结构
4.1 节点类型
5、 Container节点 (3.5.3版本新增):Container容器节点,当容器中没有任何子节点,该容器节点会被zk定期删除(定时任务默认60s 检查一次)。 和持久节点的区别是 ZK 服务端启动后,会有一个单独的线程去扫描,所有的容器节点,当发现容器节点的子节点数量为 0 时,会自动删除该节点。
6、TTL节点: 带过期时间节点,默认禁用,需要在zoo.cfg中添加extendedTypesEnabled=true 开启。 注意:TTL不能用于临时节点。
4.2 节点状态信息
类似于树状结构,节点下面是可以存储一些信息和属性的。可以通过stat命令来进行查看。
cZxid :Znode创建的事务id。
ctime:节点创建时的时间戳。
mZxid :Znode被修改的事务id,即每次对znode的修改都会更新mZxid。
mtime:节点最新一次更新发生时的时间戳。
pZxid: 表示该节点的子节点列表最后一次修改的事务ID,添加子节点或删除子节点就会影响子节点列表,但是修 改子节点的数据内容则不影响该ID。
cversion :子节点的版本号。当znode的子节点有变化时,cversion 的值就会增加1。
dataVersion:数据版本号,每次对节点进行set操作,dataVersion的值都会增加1。
ephemeralOwner:如果该节点为临时节点,ephemeralOwner值表示与该节点绑定的session id。如果不是, ephemeralOwner值为0(持久节点)。
dataLength : 数据的长度 。
numChildren :子节点的数量(只统计直接子节点的数量)
五、ZK监听机制详解
客户端再ZK服务器端注册监听,当监听事件发生时,ZK服务器端会主动通知客户端的过程,就是ZK的监听回调机制。
监听的事件类型:
None:连接建立事件
NodeCreate:节点创建
NodeDelete:节点删除
NodeDataChanged:节点数据变化
NodeChildrenChnaged:子节点列表变化事件
DataWatchRemoved:节点监听被移除
ChildWatchRemoved:子节点监听被移除
节点监听的特性:
1、一次性触发:监听是一次性的,一旦触发后,服务器端会删除监听,如果想继续监听,需要重新注册监听。
2、客户端顺序回调:监听回调是顺序性的,按照注册监听的顺序进行回调,且回调是串行执行的,所以回调逻辑不应太多,否则会影响其他客户端监听回调。
3、轻量级:回调通知中,并没有节点变化前后的内容,只包含通知状态、事件类型以及节点路径。这一点决定了ZK的监听机制实现是推拉结合模式,事件发生时,将事件推送给客户端,客户端要获取最新的数据,需要重新从ZK服务器拉取数据。
4、时效性:当客户端注册了监听,但是由于短暂的连接中断后,再有效时间内又重新连接到服务器端,客户端之前注册的监听还是存在的,当监听事件发生时,依然会通知客户端。
Zookeeper 3.6.0版本新增的功能, 在被触发之后,仍然保留,可以继续监听ZNode上的变更。
addWatch [-m mode] path
七、权限设置
ACL权限可以针对节点设置相关读写等权限,保障数据的安全性。在生产环境下,必须要这样做,否则会被扫描出漏洞。
7.1 ACL构成
zookeeper 的 acl 通过 [scheme:id:permissions] 来构成权限列表。
scheme:授权的模式,代表采用的某种权限机制,包括 world、auth、digest、ip、super 几种。
id:授权对象,代表允许访问的用户。如果我们选择采用 IP 方式,使用的授权对象可以是一个 IP 地址或 IP 地址段;而如果使用 Digest 或 Super 方式,则对应于一个用户名。如果是 World 模式,是授权系统中所有的用户。
permissions:授权的权限,权限组合字符串,由 cdrwa 组成,其中每个字母代表支持不同权限, 创建权限create(c)、删除权限 delete(d)、读权限 read(r)、写权限 write(w)、管理权限admin(a)。
7.2 auth授权模式
1、创建用户
addauth digest fox:123456
2、设置权限
setAcl /name auth:fox:123456:cdrwa
退出客户端,重新连接之后获取/name会没权限;添加授权用户(类似于登录),可以访问
7.3 digest模式
setAcl /tuling/fox digest:fox:ZsWwgmtnTnx1usRF1voHFJAYGQU=:cdrwa
其中fox后面的一串代码为加密密码,加密方式,
echo -n fox:123456 | openssl dgst -binary -sha1 | openssl base64
7.4 IP授权模式
setAcl /node-ip ip:192.168.109.128:cdwra
create /node-ip data ip:192.168.109.128:cdwra
7.5 super超级管理员模式
需要在启动脚本上通过添加JVM 参数开启:
-Dzookeeper.DigestAuthenticationProvider.superDigest=admin:<base64encoded(SHA1(123456))
八、ZK集群
8.1 集群角色
server.3=192.168.0.3:2888:3888:observer
8.2 集群架构
8.3 集群搭建
8.4 集群Leader选举原理
九、作为注册中心的案例
1、提供服务的Server 在启动的时候,将自己的ip:port信息以临时节点的方式注册到ZK集群,注册路径为 /services/serverX
2、客户端从ZK集群拉取 /services 节点下的子节点,并获取其中的数据,从而获取在线的server的信息。同时,客户端向ZK集群注册一个监听,监听/services 节点子节点的变化。
3、当Server 有宕机或者下线时。
4、因为注册的是临时节点。ZK监测到Server宕机之后,会删除临时节点,并通知注册 /services 节点子节点变化的客户端。
5、客户端收到 /services 下子节点变化的通知,主动重新拉取 /services 下的子节点数据,更新本地server列表,同时再次注册监听/services 节点的变化。
通过以上步骤,可以实现client端,最终都有一份在线的server的列表。