栏目分类:
子分类:
返回
终身学习网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
终身学习网 > IT > 软件开发 > 后端开发 > Java

zookeeper学习教程

Java 更新时间:发布时间: 百科书网 趣学号
Zookeeper学习教程 Zookeeper入门 概述

Zookeeper是一个开源的分布式的,为分布式应用提供协调服务的Apache项目。

Zookeeper从设计模式角度来理解,是一个基于观察者模式设计的分布式服务管理框架,它负责存储和管理大家都关心的数据,然后接受观察者的注册,一旦这些数据的状态发生了变化,Zookeeper就负责通知已经在Zookeeper上注册的那些观察者做出相应的反应.

特点

数据结构

ZK中没有文件的概念,节点下直接存的就是内容

下载地址

https://zookeeper.apache.org/

Zookeeper安装

本次使用的版本是:apache-zookeeper-3.5.7-bin.tar.gz

单机模式的安装以及简单操作

本地单机安装步骤

① 把软件包上传的Linux的 /opt/software 下
② 加压ZK到 /opt/module 下
③ 将加压后的目录名称修改一下:apache-zookeeper-3.5.7(选做)
④ 将zk的安装目录下 conf/zoo_sample.cfg 文件改名为 zoo.cfg
⑤ 在ZK的安装目录下创建一个新的目录zkData,作为zk的数据持久化目录
⑤ 修改zoo.cfg配置文件 dataDir=/opt/module/zookeeper-3.5.7/zkData
⑥ 配置ZK的环境变量 (选做)

启停zk服务端 和 zk客户端

# 启动zk server
zkServer.sh start
# 启动zk client
zkCli.sh -server host:port

#查看一下zk的服务端和客户端对应的进程: jps
QuorumPeerMain --> 服务端
ZooKeeperMain  --> 客户端
		  
# 退出客户端
quit

配置参数解读

# 通信心跳数,Zookeeper服务器与客户端心跳时间,单位毫秒,用于心跳机制,并且设置最小的session超时时间为两倍心跳时间,4s
tickTime=2000
# 集群中的Follower跟随者服务器与Leader领导者服务器之间初始连接时能容忍的最多心跳数(tickTime的数量),用它来限定集群中的Zookeeper服务器连接到Leader的时限。
initLimit=10
#集群中Leader与Follower之间的最大响应时间单位,假如响应超过syncLimit * tickTime,Leader认为Follwer死掉,从服务器列表中删除Follwer。
syncLimit=5

dataDir=/opt/module/zookeeper-3.5.7/zkData

clientPort=2181

搭建Zookeeper集群以及封装群启脚本

注意事项:如果不是第一次搭建集群,那么就把zk安装目录下的zkData目录
删除,并且把logs目录也删除

1. 在ZK的安装目录下创建 zkData 
	
2. 修改zoo.cfg 配置文件
	   -- 
	     dataDir=/opt/module/zookeeper-3.5.7/zkData
	   -- 
	     server.2=hadoop102:2888:3888
		 server.3=hadoop103:2888:3888
	     server.4=hadoop104:2888:3888
		 
3. 在ZK的安装目录下的zkData目录中创建一个myid的文件
	   用于标记当前服务器的编号
	   hadoop102 --> 2

	   
5. 将hadoop102的整个ZK的安装目录分发到103,104
[atguigu@hadoop102 module]$ my_rsync zookeeper-3.5.7/
	
6. 在不同机器上修改myid文件中的值 
hadoop103 --> 3
hadoop104 --> 4

至此,zk集群的配置完毕,简单把

各自启动zkServer

#  bin/zkServer.sh start
[atguigu@hadoop102 zookeeper-3.5.7]$ bin/zkServer.sh start
ZooKeeper JMX enabled by default
Using config: /opt/module/zookeeper-3.5.7/bin/../conf/zoo.cfg
Starting zookeeper ... STARTED
[atguigu@hadoop102 zookeeper-3.5.7]$ my_jps.sh 
hadoop102,hadoop103,hadoop104进程启动情况
=================hadoop102 jps情况=================
1207 Jps
1143 QuorumPeerMain
=================hadoop103 jps情况=================
1204 Jps
1150 QuorumPeerMain
=================hadoop104 jps情况=================
1612 Jps
1565 QuorumPeerMain
# 查看当前zk的状态
[atguigu@hadoop102 zookeeper-3.5.7]$ bin/zkServer.sh status
ZooKeeper JMX enabled by default
Using config: /opt/module/zookeeper-3.5.7/bin/../conf/zoo.cfg
Client port found: 2181. Client address: localhost.
Mode: follower 	# 发现为follower 从机
[atguigu@hadoop102 zookeeper-3.5.7]$ 

群启zk脚本

[atguigu@hadoop102 bin]$ pwd
/home/atguigu/bin
[atguigu@hadoop102 bin]$ touch zk_cluster.sh
[atguigu@hadoop102 bin]$ 
# 编写如下群启脚本
#!/bin/bash
if [ $# -lt 1 ]
then
	echo '参数不能为空!'
	exit
fi

for host in hadoop102 hadoop103 hadoop104
do
	case $1 in
	"start")
		echo "$1===========$host===========ZK"
		ssh $host /opt/module/zookeeper-3.5.7/bin/zkServer.sh $1
	;;
	"stop")
		echo "$1===========$host===========ZK"
		ssh $host /opt/module/zookeeper-3.5.7/bin/zkServer.sh $1
	;;
	"status")
		echo "$1===========$host===========ZK"
		ssh $host /opt/module/zookeeper-3.5.7/bin/zkServer.sh $1
	;;
	*)
		echo "$1===========参数错误==========="
		exit
	;;
	esac
done
# 授权
[atguigu@hadoop102 bin]$ chmod 744 zk_cluster.sh 
[atguigu@hadoop102 bin]$ ll
总用量 16
-rwxr--r--. 1 atguigu atguigu 945 9月  20 22:43 my_cluster.sh
-rwxr--r--. 1 atguigu atguigu 219 9月  20 17:15 my_jps.sh
-rwxr--r--. 1 atguigu atguigu 672 9月  20 00:31 my_rsync.sh
-rwxr--r--. 1 atguigu atguigu 544 9月  27 00:57 zk_cluster.sh

群启集群

[atguigu@hadoop102 module]$ zk_cluster.sh start
start===========hadoop102===========ZK
ZooKeeper JMX enabled by default
Using config: /opt/module/zookeeper-3.5.7/bin/../conf/zoo.cfg
Starting zookeeper ... STARTED
start===========hadoop103===========ZK
ZooKeeper JMX enabled by default
Using config: /opt/module/zookeeper-3.5.7/bin/../conf/zoo.cfg
Starting zookeeper ... STARTED
start===========hadoop104===========ZK
ZooKeeper JMX enabled by default
Using config: /opt/module/zookeeper-3.5.7/bin/../conf/zoo.cfg
Starting zookeeper ... STARTED
[atguigu@hadoop102 module]$ zk_cluster.sh status
status===========hadoop102===========ZK
ZooKeeper JMX enabled by default
Using config: /opt/module/zookeeper-3.5.7/bin/../conf/zoo.cfg
Client port found: 2181. Client address: localhost.
Mode: follower
status===========hadoop103===========ZK
ZooKeeper JMX enabled by default
Using config: /opt/module/zookeeper-3.5.7/bin/../conf/zoo.cfg
Client port found: 2181. Client address: localhost.
Mode: leader
status===========hadoop104===========ZK
ZooKeeper JMX enabled by default
Using config: /opt/module/zookeeper-3.5.7/bin/../conf/zoo.cfg
Client port found: 2181. Client address: localhost.
Mode: follower
[atguigu@hadoop102 module]$ 
Zookeeper实战 分布式安装部署 客户端命令行操作
# 启动zk集群
[atguigu@hadoop102 module]$ zk_cluster.sh start
# 开启客户端连接zk
[atguigu@hadoop102 module]$ bin/zkCli.sh -server hadoop102:2181

基本命令

命令基本语法功能描述
help显示所有操作命令
ls path使用 ls 命令来查看当前znode的子节点-w 监听子节点变化-s 附加次级信息
create普通创建-s 含有序列-e 临时(重启或者超时消失)
get path获得节点的值-w 监听节点内容变化-s 附加次级信息
set设置节点的具体值
stat查看节点状态
delete删除节点
deleteall递归删除节点
1)启动客户端
[atguigu@hadoop103 zookeeper-3.5.7]$ bin/zkCli.sh
2)显示所有操作命令
[zk: localhost:2181(CONNECTED) 1] help
3)查看当前znode中所包含的内容
[zk: localhost:2181(CONNECTED) 0] ls /
[zookeeper]
4)查看当前节点详细数据
[zk: localhost:2181(CONNECTED) 1] ls -s /
[zookeeper]
cZxid = 0x0
ctime = Thu Jan 01 08:00:00 CST 1970
mZxid = 0x0
mtime = Thu Jan 01 08:00:00 CST 1970
pZxid = 0x0
cversion = -1
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 0
numChildren = 1
5)分别创建2个普通节点
[zk: localhost:2181(CONNECTED) 3] create /sanguo "diaochan"
Created /sanguo
[zk: localhost:2181(CONNECTED) 4] create /sanguo/shuguo "liubei"
Created /sanguo/shuguo
6)获得节点的值
[zk: localhost:2181(CONNECTED) 5] get /sanguo
diaochan
[zk: localhost:2181(CONNECTED) 6] get -s /sanguo
diaochan
cZxid = 0x100000003
ctime = Wed Aug 29 00:03:23 CST 2018
mZxid = 0x100000003
mtime = Wed Aug 29 00:03:23 CST 2018
pZxid = 0x100000004
cversion = 1
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 7
numChildren = 1
[zk: localhost:2181(CONNECTED) 7]
[zk: localhost:2181(CONNECTED) 7] get -s /sanguo/shuguo
liubei
cZxid = 0x100000004
ctime = Wed Aug 29 00:04:35 CST 2018
mZxid = 0x100000004
mtime = Wed Aug 29 00:04:35 CST 2018
pZxid = 0x100000004
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 6
numChildren = 0
7)创建临时节点
[zk: localhost:2181(CONNECTED) 7] create -e /sanguo/wuguo "zhouyu"
Created /sanguo/wuguo
(1)在当前客户端是能查看到的
[zk: localhost:2181(CONNECTED) 3] ls /sanguo 
[wuguo, shuguo]
(2)退出当前客户端然后再重启客户端
[zk: localhost:2181(CONNECTED) 12] quit
[atguigu@hadoop104 zookeeper-3.5.7]$ bin/zkCli.sh
(3)再次查看根目录下短暂节点已经删除
[zk: localhost:2181(CONNECTED) 0] ls /sanguo
[shuguo]
8)创建带序号的节点
	(1)先创建一个普通的根节点/sanguo/weiguo
[zk: localhost:2181(CONNECTED) 1] create /sanguo/weiguo "caocao"
Created /sanguo/weiguo
	(2)创建带序号的节点
[zk: localhost:2181(CONNECTED) 2] create /sanguo/weiguo "caocao"
Node already exists: /sanguo/weiguo
[zk: localhost:2181(CONNECTED) 3] create -s /sanguo/weiguo "caocao"
Created /sanguo/weiguo0000000000
[zk: localhost:2181(CONNECTED) 4] create -s /sanguo/weiguo "caocao"
Created /sanguo/weiguo0000000001
[zk: localhost:2181(CONNECTED) 5] create -s /sanguo/weiguo "caocao"
Created /sanguo/weiguo0000000002
[zk: localhost:2181(CONNECTED) 6] ls /sanguo
[shuguo, weiguo, weiguo0000000000, weiguo0000000001, weiguo0000000002, wuguo]
[zk: localhost:2181(CONNECTED) 6]
如果节点下原来没有子节点,序号从0开始依次递增。如果原节点下已有2个节点,则再排序时从2开始,以此类推。
9)修改节点数据值
[zk: localhost:2181(CONNECTED) 6] set /sanguo/weiguo "caopi"
10)节点的值变化监听
	(1)在hadoop104主机上注册监听/sanguo节点数据变化
[zk: localhost:2181(CONNECTED) 26] [zk: localhost:2181(CONNECTED) 8] get -w /sanguo
	(2)在hadoop103主机上修改/sanguo节点的数据
[zk: localhost:2181(CONNECTED) 1] set /sanguo "xishi"
	(3)观察hadoop104主机收到数据变化的监听
WATCHER::
WatchedEvent state:SyncConnected type:NodeDataChanged path:/sanguo
11)节点的子节点变化监听(路径变化)
	(1)在hadoop104主机上注册监听/sanguo节点的子节点变化
[zk: localhost:2181(CONNECTED) 1] ls -w /sanguo
[aa0000000001, server101]
	(2)在hadoop103主机/sanguo节点上创建子节点
[zk: localhost:2181(CONNECTED) 2] create /sanguo/jin "simayi"
Created /sanguo/jin
	(3)观察hadoop104主机收到子节点变化的监听
WATCHER::
WatchedEvent state:SyncConnected type:NodeChildrenChanged path:/sanguo
12)删除节点
[zk: localhost:2181(CONNECTED) 4] delete /sanguo/jin
13)递归删除节点
[zk: localhost:2181(CONNECTED) 15] deleteall /sanguo/shuguo
14)查看节点状态
[zk: localhost:2181(CONNECTED) 17] stat /sanguo
cZxid = 0x100000003
ctime = Wed Aug 29 00:03:23 CST 2018
mZxid = 0x100000011
mtime = Wed Aug 29 00:21:23 CST 2018
pZxid = 0x100000014
cversion = 9
dataVersion = 1
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 4
numChildren = 1
Zookeeper内部原理 节点类型
  • 持久(Persistent)

    客户端和服务器端断开连接后,创建的节点不删除

  • 短暂(Ephemeral)

    客户端和服务器端断开连接后,创建的节点自己删除

(1)持久化目录节点
客户端与zk断开连接后,该节点依旧存在
(2)持久化顺序编号目录节点
客户端与zk断开连接后,该节点依旧存在,只是zk给该节点名称进行顺序编号
(3)临时目录节点
客户端与zk断开连接后,该节点被删除
(4)临时顺序编号目录节点
客户端与zk断开连接后,该节点被删除,只是zk给该节点名称进行顺序编号
Stat结构体

使用 stat 路径命令可获得一个结构体对象

[zk: hadoop102:2181(CONNECTED) 6] stat /
cZxid = 0x0
ctime = Thu Jan 01 08:00:00 CST 1970
mZxid = 0x0
mtime = Thu Jan 01 08:00:00 CST 1970
pZxid = 0x200000018
cversion = 7
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 0
numChildren = 1
# 属性解释
(1)czxid-创建节点的事务zxid
每次修改ZooKeeper状态都会收到一个zxid形式的时间戳,也就是ZooKeeper事务ID。
事务ID是ZooKeeper中所有修改总的次序。每个修改都有唯一的zxid,如果zxid1小于zxid2,那么zxid1在zxid2之前发生。
(2)ctime - znode被创建的毫秒数(从1970年开始)
(3)mzxid - znode最后更新的事务zxid
(4)mtime - znode最后修改的毫秒数(从1970年开始)
(5)pZxid-znode最后更新的子节点zxid
(6)cversion - znode子节点变化号,znode子节点修改次数
(7)dataversion - znode数据变化号
(8)aclVersion - znode访问控制列表的变化号
(9)ephemeralOwner- 如果是临时节点,这个是znode拥有者的session id。如果不是临时节点则是0。
(10)dataLength- znode的数据长度
(11)numChildren - znode子节点数量
监听器原理

总结大致原理

zookeeper其实本质上就是一个文件系统加通知机制的这么一个框架,咱们通常用的都是管理一些框架的综合信息来协调我们整个各个服务之间的一个工作,首先呢,我们这个服务会到zookeeper去注册自己,注册的时候呢,其实就是在这个zookeeper的这个监听列表里边也添加一个监听事件。然后呢,我们在获取zookeeper连接对象的时候,在这个watcher对象里边去写这个提供好这个process的方法,只要我们将来啊,只要将来这个zookeeper上维护的数据发生了变化,它立刻会通过这个监听列表找到我,然后调用我listener这个线程啊。从而调用我的process方法,然后通知到我,做相应的变化就可以了。
选举机制

选举机制总原则:集群中的每台机器都参与投票,通过交换选票得到每台机器的最终得票,一旦出现得票数超过机器总数一半以上数量,当前机器即为leader。

举例说明

场景1:以5台机器为例,集群的机器顺时启动,当前集群中没有任何数据。

①. server1 启动,首先server1给自己投一票,然后看当前票数是否超过半数,结果没有超过, 这时候leader就没选出来,当前选举状态是Locking状态。
		  
②. server2 启动,首先server2先给自己投一票,因为当前集群已经有两台机器已启动,所以server1,server2会交换选票,交换后发现各自有一票,接下来比较myid 发现server2的myid值 > server2的myid值,此时server2胜出,最后server2有两票。最后再看当前票数是否半,发现未过半,集群的选举状态.集训保持locking状态。
		
③. server3启动, 首先自己投自己一票,server1和server2也会投自己一票,然后交换选票发现都一样, 接着比较myid 最后server3胜出,此时server3就有3票,同时server3的票数超过半数。所以server3成为 leader。
		  
④. server4启动,发现当前集群已经有leader 它自己自动成为follower
	   
⑤. server5启动,发现当前集群已经有leader 它自己自动成为follower

场景2:以5台机器为例,当前集群正在使用(有数据/没数据),leader突然宕机的情况。

当集群中的leader挂掉,集群会重新选出一个leader,此时首先会比较每一台机器的czxid, czxid最大的被选为leader。极端情况,czxid都相等的情况,那么就会直接比较myid。

一般情况下ZK集群更推荐使用奇数台机器原因?

在ZK集群中 奇数台 和 偶数台(接近的台数) 机器的容错能力是一样的,所以在考虑资源节省的情况,我们推荐使用奇数台方案
写数据流程

1. 客户端会向ZK集群中的一台机器server1发送写数据的请求。
2. server1接收到请求后,马上会通知leader 有写数据的请求来了
3. leader拿到请求后,进行广播,让集群每一台机器都准备要写数据
4. 集群中的所有机机器接收到leader广播后都回应一下leader
5. leader再次进行广播 开始写数据,其他机器接收到广播后也开始写数据
6. 数据成功写入后,回应leader,最后由leader来做整个事务提交
7. 当数据成功写入后,有最初和客户端发生连接的 server1 回应客户端数据写入成功。
转载请注明:文章转载自 www.051e.com
本文地址:http://www.051e.com/it/274703.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 ©2023-2025 051e.com

ICP备案号:京ICP备12030808号