zookeeper
一、zookeeper概述
- Apache Zookeeper(简称zk)是一个提供分布式协调服务的开源框架
- zk主要是用来解决分布式应用中经常遇到的一些数据管理问题,如:状态同步服务、集群选举管理、分布式应用配置项的管理等。
- zookeeper本质上是一个分布式的小文件存储系统,提供基于类似文件系统的目录树方式的数据存储,并且可以对树中的节点进行有效管理,从而用来维护和监控存储的数据的状态变化。通过这些数据状态的变化,从而可以达到基于数据的集群管理。
- 文件存储系统:存储文件数据的,文件系统,有目录树结构
- 小文件存储系统:存储数据有容量限制
- 分布式小文件存储系统:意味着zk自己也是分布式软件,多台机器存储。是标准的主从架构集群
- 主角色:leader 从角色:follower
二、zookeeper特性
全局数据一致性
zk集群中每个服务器保存一份相同的数据副本,客户端无论连接到哪个服务器,展示的数据都是一致的
zk集群式标准的主从架构集群
-
主角色(leader):事务请求(写操作)的唯一调度和处理者,保证集群事务处理的顺序性
-
从角色(follower):处理客户端非事务(读操作)请求,转发事务请求给leader,参与集群Leader选举投票
- 读操作(非事务性操作):主从角色都可以直接处理读操作,直接返回结果给客户端
- 写操作:(事务性操作):如果从角色接收到写操作,内部转发给leader,由leader全局统一编号,顺序执行
-
观察者角色(Observer,可选角色):通常用于在不影响集群事务处理能力的前提下提升集群的非事务处理能力
- 对于非事务请求可以独立处理,对于事务请求,则会转发非leader进行处理
- 不会参与任何形式的投票只提供非事务服务
- 可靠性:如果消息被其中一台服务器接受,那么将被所有的服务器接受。
- 顺序性:包括全局有序和偏序两种:全局有序是指如果在一台服务器上消息a在消息b前发布,则在所有Server上消息a都将在消息b前被发布;偏序是指如果一个消息b在消息a后被同一个发送者发布,a必将排在b前面。
- 数据更新原子性:一次数据更新要么成功(半数以上节点成功),要么失败,不存在中间状态
- 实时性:Zookeeper保证客户端将在一个时间间隔范围内获得服务器的更新信息,或者服务器失效的信息
三、Apache zookeeper集群搭建
Zookeeper集群搭建指的是ZooKeeper分布式模式安装。通常由2n+1台servers组成。这是因为为了保证Leade选举(基于Paxos算法的实现)能过得到多数的支持,所以ZooKeeper集群的数量一般为奇数。
step1:服务器基础环境
在安装zk软件之前,需要保证服务器基础环境一致:具体查看《大数据集群服务器环境配置与搭建》
- IP
- 主机名
- hosts映射
- 防火墙关闭
- 时间同步
- ssh免密登陆
step2:JDK安装与配置环境变量
#上传安装包到/export/server下
jdk-8u65-linux-x64.tar.gz
#解压到当前目录
tar zxvf jdk-8u65-linux-x64.tar.gz
#删除红色安装包(可选)
rm -rf jdk-8u65-linux-x64.tar.gz
#配置环境变量
vim /etc/profile #G + o
export JAVA_HOME=/export/server/jdk1.8.0_65
export PATH=$PATH:$JAVA_HOME/bin
export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
#重新价值环境变量文件 让配置生效
source /etc/profile
[root@node1 ~]# java -version
java version "1.8.0_65"
Java(TM) SE Runtime Environment (build 1.8.0_65-b17)
Java HotSpot(TM) 64-Bit Server VM (build 25.65-b01, mixed mode)
Step3:安装与修改zk配置文件
- 在其中一台服务器(node1)配置
#安装包
zookeeper-3.4.6.tar.gz
#上传 解压 重命名
cd /export/server
tar zxvf zookeeper-3.4.6.tar.gz
mv zookeeper-3.4.6/ zookeeper
#修改配置文件
#zk默认加载的配置文件是zoo.cfg 因此需要针对模板进行修改。保证名字正确。
cd zookeeper/conf
mv zoo_sample.cfg zoo.cfg
vi zoo.cfg
#修改
dataDir=/export/data/zkdata
#文件最后添加 2888心跳端口 3888选举端口
server.1=node1:2888:3888 # 选举端口:在选举的时候需要发送信息
server.2=node2:2888:3888 # 心跳端口:心跳机制:分布式软件中从角色向主角色进行心跳报活 server.3=node3:2888:3888
#在每台机器的dataDir指定的目录下创建一个文件 名字叫做myid
#myid里面的数字就是该台机器上server编号。server.N N的数字就是编号
[root@node1 conf]# mkdir -p /export/data/zkdata
[root@node1 conf]# echo 1 >/export/data/zkdata/myid
Step4:同步zk安装包与配置文件
- 将node1中的zk安装包与修改好的配置 scp到其他服务器
#node1 scp安装包
cd /export/server
scp -r zookeeper/ node2:$PWD
scp -r zookeeper/ node3:$PWD # 这里若不是在相对目录下,则需要写绝对路径
# 比如 : scp -r /export/server/zookeeper root@node3:/export/server
#分别在node2 node3执行
[root@node2 ~]# mkdir -p /export/data/zkdata
[root@node2 ~]# echo 2 > /export/data/zkdata/myid
[root@node3 ~]# mkdir -p /export/data/zkdata
[root@node3 ~]# echo 3 > /export/data/zkdata/myid
Step5:zk集群启停
- 需要在 每台机器上分别单独启动服务
#在哪个目录执行启动命令 默认启动日志就生成当前路径下 叫做zookeeper.out
/export/server/zookeeper/bin/zkServer.sh start
#节点状态查看 3台都启动完毕之后查看
/export/server/zookeeper/bin/zkServer.sh status
#节点服务关闭
/export/server/zookeeper/bin/zkServer.sh stop
- 注意:启动全部机器后,查看状态信息才会显示正常
Step6:查看进程、状态、日志
- zk启动之后,会有一个java进程存在,进程名叫做:QuorumPeerMain(jps查看java进程)
- 整个集群启动成功完毕之后,可以使用bin/zkServer.sh status 查看进程状态,角色类型
- 如果发现进程不存在,或者状态异常,可以根据日志排查。默认日志在执行启动命令的路径下生成zookeeper.out
扩展:shell脚本一键启停
- 编写shell脚本,实现在node1执行脚本,shell脚本ssh到各个机器启停zk服务
- 前提:配置好ssh免密登陆
# 启动
[root@node1 ~]# vim startZk.sh
#!/bin/bash
hosts=(node1 node2 node3)
for host in ${hosts[*]}
do
ssh $host "source /etc/profile;/export/server/zookeeper/bin/zkServer.sh start"
done
# 暂停
[root@node1 ~]# vim stopZk.sh
#!/bin/bash
hosts=(node1 node2 node3)
for host in ${hosts[*]}
do
ssh $host "/export/server/zookeeper/bin/zkServer.sh stop"
done
四、zookeeper 数据类型
概述
- 在结构上与标准文件系统非常类似,拥有一个层次的命名空间,都是采用树形层次结构
- Zookeeper树中的每个节点被称为:Znode,没有文件和目录之分。
- Znode兼具文件和目录两种特点
- Znode存储数据大小有限制,通常以KB为大小单位
- Znode通过路径引用路径,路径必须式绝对的,因此zk路径必须由斜杠字符/来开头,且路径唯一
Znode
-
zk数据模型树中的每个节点被称为一个znode,兼具目录文件两种特点
-
每个znode由3部分组成
- stat:此为状态信息,描述该Znode的版本,权限等信息
- data:与该Znode关联的数据
- children:该znode下的子节点
zonde stat状态信息
-
dataVersion:数据版本号,每次对节点进行set操作,dataVersion的值都会增加1(即使设置的是相同的数据)
-
cversion:子节点的版本号,当znode的子节点有变化,cversion的值就会增加1
-
cZxid:znode创建的事务id
-
mZxid:znode被修改的事务id,即每次对zonde的修改都会更新mZxid
- 对于zk来说,每次的变化都会产生一个唯一的事务id,zxid(ZooKeeper Transaction Id)。通过zxid,可以确定更新操作的先后顺序。例如,如果zxid1小于zxid2,说明zxid1操作先于zxid2发生,zxid对于整个zk都是唯一的。
-
ctime:节点创建是的时间戳
-
mtime:节点最新一次更新发生时的时间戳
-
ephemeralOwner:如果该节点为临时节点,ephemeralOwner值表示与该节点绑定的session id。如果不是,ephemeralOwner值为0
- 在client和server通信之前,首先需要建立连接,该连接称为session。连接建立后,如果发生连接超时、授权失败,或者显式关闭连接,连接便处于CLOSED状态, 此时session结束。
znode类型
- 永久节点(PERSISTENCE)
- 临时节点(EPHEMERAL)
- 永久节点序列化(PERSISTENCE_SEQUENTIAL)
- 临时节点序列化(EPHEMERAL_SEQUENTIAL)
临时\永久
临时、永久区别:创建的znode生命周期是否和创建其客户端的session状态有关
- 如客户端session结束,znode被自动删除-----> 临时节点(ephemeral node)
- 如客户端session结束,znode依然存在,除非手动强制删除-----> 永久节点(persistence node)
注意:临时节点不允许拥有子节点
序列化特性
开启序列化之后,会自动追加一个不断增加的序列号,记录每个子节点创建的先后顺序
序列号对于此节点的父节点来说是唯一的,由10位数字组成
五、zookeeper监听机制
ZooKeeper提供了分布式数据发布/订阅功能,一个典型的发布/订阅模型系统定义了一种一对多的订阅关系,能让多个订阅者同时监听某一个主题对象,当这个主题对象自身状态变化时,会通知所有订阅者,使他们能够做出相应的处理。
ZooKeeper中,引入了Watcher机制来实现这种分布式的通知功能。ZooKeeper允许客户端向服务端注册一个Watcher监听,当服务端的一些事件触发了这个Watcher,那么就会向指定客户端发送一个事件通知来实现分布式的通知功能。
触发事件种类很多,如:节点创建,节点删除,节点改变,子节点改变等。
总的来说可以概括Watcher为以下三个过程:客户端向服务端注册Watcher、服务端事件发生触发Watcher、客户端回调Watcher得到触发事件情况
watch机制特点
一次性触发
事件发生触发监听,一个watcher event就会被发送到设置监听的客户端,这种效果是一次性的
事件封装
zooKeeper使用WatchedEvent对象来封装服务端事件并传递。
WatchedEvent包含了每一个事件的三个基本属性:
通知状态(keeperState),事件类型(EventType)和节点路径(path)
event异步发送
watch的通知事件从服务端发送到客户端是异步的
先注册再触发
客户端必须先注册监听事件,服务端才可以开启监听动作
六、zookeeper shell操作
zk 的本质是文件存储系统,所以zk的核心操作就是客户端对目录树的进行增删改查操作
zk自带了一个shell客户端:/export/server/zookeeper/bin/zkCli.sh
zookeeper客户端命令
ZooKeeper -server host:port cmd args
stat path [watch]
set path data [version]
ls path [watch]
delquota [-n|-b] path
ls2 path [watch]
setAcl path acl
setquota -n|-b val path
history
redo cmdno
printwatches on|off
delete path [version]
sync path
listquota path
rmr path
get path [watch]
create [-s] [-e] path data acl
addauth scheme auth
quit
getAcl path
close
connect host:port
启动客户端
zkCli.sh # 连接本机zk服务器
zkCli.sh # 连接其他zk服务器
查看子节点 ls
[zk: localhost:2181(CONNECTED) 0] ls /
[zookeeper, itcast]
创建子节点 create
# 创建持久节点
[zk: localhost:2181(CONNECTED) 1] create /ange hello,zk
Created /itheima
# 创建永久顺序节点
create -s /ange1 hello,zk
# 创建临时节点
create -e /ange2 hello,zk
# 创建临时顺序节点
create -e -s /ange3 hello,zk
获取节点信息 get
[zk: localhost:2181(CONNECTED) 3] get /ange
hello,zk
cZxid = 0x400000005
ctime = Wed Aug 18 14:21:13 CST 2021
mZxid = 0x400000005
mtime = Wed Aug 18 14:21:13 CST 2021
pZxid = 0x400000005
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 8
numChildren = 0
更新节点数据 set
[zk: localhost:2181(CONNECTED) 5] set /ange bye,zk
cZxid = 0x400000005
ctime = Wed Aug 18 14:21:13 CST 2021
mZxid = 0x400000006
mtime = Wed Aug 18 14:23:40 CST 2021
pZxid = 0x400000005
cversion = 0
dataVersion = 1 # 更新节点 +1
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 6
numChildren = 0
删除节点 delete\ rmr
[zk: localhost:2181(CONNECTED) 1] ls /
[zookeeper, ange, itcast]
[zk: localhost:2181(CONNECTED) 2] rmr /itcast
[zk: localhost:2181(CONNECTED) 3] ls /
[zookeeper, ange]
[zk: localhost:2181(CONNECTED) 4] delete /ange
[zk: localhost:2181(CONNECTED) 5] ls /
[zookeeper]
[zk: localhost:2181(CONNECTED) 6]
- delete 只能删除叶子节点
- rmr可以删除非叶子节点(递归删除)
监听机制:
node1:设置监听
[zk: localhost:2181(CONNECTED) 13] get /itcast watch
hello,zk
cZxid = 0x400000002
ctime = Wed Aug 18 13:27:27 CST 2021
mZxid = 0x400000002
mtime = Wed Aug 18 13:27:27 CST 2021
pZxid = 0x400000002
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 8
numChildren = 0
node3:修改监听节点
[zk: node3(CONNECTED) 0] set /itcast 123456
cZxid = 0x400000002
ctime = Wed Aug 18 13:27:27 CST 2021
mZxid = 0x400000010
mtime = Wed Aug 18 14:28:23 CST 2021
pZxid = 0x400000002
cversion = 0
dataVersion = 1
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 6
numChildren = 0
node1:得到反馈
[zk: localhost:2181(CONNECTED) 14]
WATCHER::
WatchedEvent state:SyncConnected type:NodeDataChanged path:/itcast
标签:zk,zookeeper,export,path,概述,客户端,节点,搭建
From: https://www.cnblogs.com/luoluoange/p/18073775