ZooKeeper是一个开源的分布式数据一致性解决方案,致力于为分布式应用提供一个高性能、高可用,且具有严格顺序访问控制功能的分布式协调服务。
分布式应用程序可以基于ZooKeeper实现数据发布与订阅、负载均衡(dubbo利用了zookeeper机制实现负载均衡)、命名服务、分布式协调与通知、集群管理、Leader选举、分布式锁、分布式队列等功能。
新建一个Java目录,然后定位到我们安装包的目录,再进行解压
mkdir /usr/local/java
cd /soft/
tar -zvxf jdk-8u161-linux-x64.tar.gz -C /usr/local/java/
配置环境变量
vim /etc/profile
在文本末尾加入如下配置
# java
export JAVA_HOME=/usr/local/java/jdk1.8.0_211
export JRE_HOME=/usr/local/java/jdk1.8.0_211/jre
export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JRE_HOME/lib
export PATH=$JAVA_HOME/bin:$JRE_HOME/bin:$PATH
刷新配置,查看Java是否安装成功
source /etc/profile
java -version
下载zookeeper的安装包
http://apache.fayea.com/zookeeper/stable/zookeeper-3.4.10.tar.gz
解压zookeeper
tar -zxvf zookeeper-3.4.10.tar.gz
cd 到 ZK_HOME/conf , copy一份zoo.cfg
cp zoo_sample.cfg zoo.cfg
sh zkServer.sh
{start|start-foreground|stop|restart|status|upgrade|print-cmd}
sh zkCli.sh -server ip:port(默认端口2181)
第一步: 修改配置文件zoo.cfg(集群中每个节点都要修改)
server.id=host:port:port
id的取值范围: 1~255; 用id来标识该机器在集群中的机器序号
2888是follower节点与leader节点交换信息的端口;
3181是leader选举端口(端口号均为自定义,只要每台服务器保持相同的选举端口且该端口未被其它端口占用即可)
server.1=192.168.123.45:2888:3181
server.2=192.168.123.55:2888:3181
server.3=192.168.123.38:2888:3181
第二步:创建myid
在每一个服务器的dataDir目录(Linux上默认是/tmp/zookeeper)下创建一个myid的文件,文件内写上每台机器对应的server.id的id值
第三步:关闭防火墙,启动zookeeper
Systemctl stop firewalld
./zkServer.sh start
./zkServer.sh status查看状态,看到如下显式,即为成功
第一步:修改zoo.cfg配置文件(增加“peerType=observer”,observer服务器后面增加“:observer”)
peerType=observer
server.1=192.168.123.45:2888:3181
server.2=192.168.123.55:2888:3181
server.3=192.168.123.38:2888:3181
server.4=192.168.123.174:2888:3181:observer
第二步:配置observer服务器的myid
在observer服务器的dataDir目录(Linux上默认是/tmp/zookeeper)下创建一个myid的文件,文件内写上observer对应的server.id的id值
第三部:关闭防火墙,开启集群
leader和follower是通过算法选举的,不是固定的某一台服务器,而observer角色则是可通过zoo.cfg配置文件指定的
tickTime=2000 zookeeper中最小的时间单位长度,ms
initLimit=10 follower启动后与leader完成数据同步的时间,即10*tickTime=20秒
syncLimit=5 leader和follower进行心跳检测的最大延时时间
dataDir=/tmp/zookeeper 表示zookeeper服务器存储快照文件的目录
dataLogDir 配置 zookeeper事务日志的存储路径,默认指定在dataDir目录下
clientPort 客户端和服务端建立连接的端口号:2181(默认)
在谈到分布式的时候,我们通常说的“节点"是指组成集群的每一台机器。而在 ZooKeeper中,“节点"分为两类:
第一类同样是指构成集群的机器,我们称之为机器节点;
第二类则是指数据模型中的数据单元,我们称之为数据节点一ZNode。
ZooKeeper 将所有数据存储在内存中,数据模型是一棵文件树(Znode Tree),由斜杠“/”进行路径的分割,例如/foo/path1。每个节点上都会保存自己的数据内容,同时还会保存一系列属性信息。
在 Zookeeper 中,Node 可以分为持久节点和临时节点两类。所谓持久节点是指一旦这个 ZNode 被创建了,除非主动进行 ZNode 的移除操作,否则这个 ZNode 将一直保存在 ZooKeeper 上。而临时节点就不一样了,它的生命周期和客户端会话绑定,一旦客户端会话失效,那么这个客户端创建的所有临时节点都会被移除。另外,ZooKeeper 还允许用户为每个节点添加一个特殊的属性:Sequential(有序的)。
一旦节点被标记上这个属性,那么在这个节点被创建的时候,ZooKeeper 会自动在其节点名后面追加上一个整型数字,这个整型数字是一个由父节点维护的自增数字。节点的具体分类:
Session指的是ZooKeeper服务器与客户端的会话。在ZooKeeper中,一个客户端连接是指客户端和服务器之间的一个TCP长连接。客户端启动的时候,首先会与服务器建立一个 TCP 连接,从第一次连接建立开始,客户端会话的生命周期也开始了。
通过这个连接,客户端能够通过心跳检测与服务器保持有效的会话,也能够向 Zookeeper 服务器发送请求并接受响应,同时还能够通过该连接接收来自服务器的 Watch 事件通知。Session 的 sessionTimeout 值用来设置一个客户端会话的超时时间。
当服务器压力太大、网络故障或是客户端主动断开连接等各种原因导致客户端连接断开时,只要在 sessionTimeout 规定的时间内能够重新连接上集群中任意一台服务器,那么之前创建的会话仍然有效。
在为客户端创建会话之前,服务端首先会为每个客户端都分配一个 sessionID。由于 sessionID 是 Zookeeper 会话的一个重要标识,许多与会话相关的运行机制都是基于这个 sessionID 的。因此,无论是哪台服务器为客户端分配的 sessionID,都务必保证全局唯一。
ZooKeeper命名空间中的每个znode都有一个与之关联的stat结构,类似于Unix/Linux文件系统中文件的stat结构。 znode的stat结构中的字段显示如下,各自的含义如下:
cversion = 0 childrenversion子节点的版本号
aclVersion = 0 表示acl(access control)的版本号,修改节点权限
dataVersion = 1 表示的是当前节点数据的版本号
czxid create节点被创建时的事务ID
mzxid modify节点最后一次被更新的事务ID
pzxid 当前节点下的子节点最后一次被修改时的事务ID
ctime = 创建时间
mtime = 修改时间
ephemeralOwner = 0x0 (创建临时节点的时候,会有一个sessionId,该值存储的就是这个sessionid)
dataLength = 3 数据值长度
numChildren = 0 子节点数
Watcher(事件监听器),是ZooKeeper中的一个很重要的特性。zookeeper提供了分布式数据发布/订阅,允许客户端向服务器注册一个watcher监听。当服务器端的节点触发指定事件的时候会触发watcher。服务端会向客户端发送一个事件通知,watcher的通知是一次性的,一旦触发一次通知后,该watcher就失效,该机制是 ZooKeeper 实现分布式协调服务的重要特性。
ZooKeeper采用ACL(AccessControlLists)策略来进行权限控制,类似于UNIX文件系统的权限控制。ZooKeeper 定义了 5 种权限,如下:
Create:创建子节点的权限
Read:获取节点数据和子节点列表的权限
Writer:修改节点数据的权限
Delete:删除子节点的权限
Admin:设置节点ACL的权限
其中尤其需要注意的是,CREATE 和 DELETE 这两种权限都是针对子节点的权限控制。
zookeeper提供控制节点访问权限的功能,用于有效的保证zookeeper中数据的安全性。避免误操作而导致系统出现重大事故。
Tips:zookeeper并不是用来存储数据的,通过监控数据状态的变化,达到基于数据的集群管理。
create [-s] [-e] path data acl
-s 表示节点是否有序
-e 表示是否为临时节点
通过s和e可以创建出四种不同特性的节点,默认情况下,是持久化节点
get path [watch]
获得指定 path的信息
set path data [version]
修改节点 path对应的data
delete path [version]
删除节点