Zookeeper
文章目录 |
---|
Zookeeper 教程 | 菜鸟教程 (runoob.com) |
Zab协议 (史上最全) - 疯狂创客圈 - 博客园 (cnblogs.com) |
/ |
一、初探茅庐
ZooKeeper是什么?
分布式应用程序协调服务,提供了分布式独享锁、选举、队列的接口,作为服务间的协调注册中心。
![](https://csdn-pic-1301850093.cos.ap-guangzhou.myqcloud.com/csdn-pic/Zookeeper-CAP理论图-1.png)
同时,它也是Hadoop的正式子项目,是一个针对大型分布式系统的可靠协调系统,提供的功能包括配置维护、名字服务、分布式同步、组服务等
而实际上它在生产环境可以作用于:
- 服务监控系统
- 大数据平台的分布式调度系统
- 其他…
Zookeeper是保证了C+P(一致性+分区容错性)
1.1 Linux环境部署
文章目录 |
---|
Index of /zookeeper/zookeeper-3.7.0 (apache.org) |
单机部署
下载安装包
## md5:8ffa97e7e6b0b2cf1d022e5156a7561a
wget https://downloads.apache.org/zookeeper/zookeeper-3.7.0/apache-zookeeper-3.7.0-bin.tar.gz
tar -zxvf apache-zookeeper-3.7.0-bin.tar.gz
## 修改zoo_sample.cfg文件为zoo.cfg
cd apache-zookeeper-3.7.0-bin/conf
接下来看看zoo.cfg配置文件
# The number of milliseconds of each tick
# Client-Server通信心跳时间
# 服务器之间或客户端与服务器之间维持心跳的时间间隔
tickTime=2000
# The number of ticks that the initial
# synchronization phase can take
# Leader-Follower初始通信时限
# 集群中的follower服务器(F)与leader服务器(L)之间初始连接时能容忍的最多心跳数(tickTime的数量)
initLimit=10
# The number of ticks that can pass between
# sending a request and getting an acknowledgement
# 集群中的follower服务器与leader服务器之间请求和应答之间能容忍的最多心跳数(tickTime的数量)
syncLimit=5
# the directory where the snapshot is stored.
# do not use /tmp for storage, /tmp here is just
# example sakes.
# 数据文件目录
dataDir=/tmp/zookeeper
# the port at which the clients will connect
# 客户端连接端口
clientPort=2181
# the maximum number of client connections.
# increase this if you need to handle more clients
# 对于一个客户端的连接数限制
maxClientCnxns=60
#
# Be sure to read the maintenance section of the
# administrator guide before turning on autopurge.
#
# http://zookeeper.apache.org/doc/current/zookeeperAdmin.html#sc_maintenance
#
# The number of snapshots to retain in dataDir
# 日志清理,多少个快照清理一次,先入先出
#autopurge.snapRetainCount=3
# Purge task interval in hours
# Set to "0" to disable auto purge feature
# 日志清理,多少个小时清理一次
#autopurge.purgeInterval=1
# 服务器名称与地址:集群信息(服务器编号,服务器地址,LF集群内机器通信端口,选举端口)
# server.N=YYY:A:B
# server.1=192.168.3.33:2888:3888
# server.2=192.168.3.35:2888:3888
# server.3=192.168.3.37:2888:3888
## Metrics Providers
#
# https://prometheus.io Metrics Exporter
#metricsProvider.className=org.apache.zookeeper.metrics.prometheus.PrometheusMetricsProvider
#metricsProvider.httpPort=7000
#metricsProvider.exportJvmInfo=true
启动
## 启动
sh ./zkServer.sh start
## 查看状态
sh ./zkServer.sh status
你学废了吗
集群部署
按照上述步骤部署完成后,先把conf文件的集群配置修改,因为我是只有一台机器做测试,所以这些端口都不能一样不然会冲突
有一个快速清空vim内容的办法
- 先按gg到游标顶部
- 按dG,会删除掉游标屁股后面的所有内容
tickTime=2000
initLimit=10
syncLimit=5
dataDir=/tmp/zookeeper-2
clientPort=2192
maxClientCnxns=60
server.1=127.0.0.1:2881:3881
server.2=127.0.0.1:2882:3882
server.3=127.0.0.1:2883:3883
在每个Zookeeper的数据目录下创建myid文件
touch /tmp/zookeeper-3/myid
touch /tmp/zookeeper-2/myid
touch /tmp/zookeeper-1/myid
chmod 755 /tmp/zookeeper-3/myid
chmod 755 /tmp/zookeeper-2/myid
chmod 755 /tmp/zookeeper-1/myid
echo 3 > /tmp/zookeeper-3/myid
echo 2 > /tmp/zookeeper-2/myid
echo 1 > /tmp/zookeeper-1/myid
启动,查看启动的状态
sh apache-zookeeper-3.7.0-bin-1/bin/zkServer.sh start
sh apache-zookeeper-3.7.0-bin-2/bin/zkServer.sh start
sh apache-zookeeper-3.7.0-bin-3/bin/zkServer.sh start
你又学废了吗
1.2 使用场景
Zookeeper可靠的锁机制及集群选举,注定了它是用于大规模集群下的分布式协调
场景,一般来说会用于
- 分布式系统中的主节点选举
- 分布式锁与队列/协调与通知
- 负载均衡
- 发布/订阅
同时,它也是作为大数据平台中Hadoop、Spark中非常重要的一环。
1.3 集群角色
集群中的角色简单描述有四种
- 主节点 leader
- 从节点 follower
- 观察者节点 observer
- 客户端 client
可以通过命令查看节点状态
关于observer
在zookeeper 3.3后引入的新角色,不参与投票、选举,只提供非事务服务,并且接受客户端连接,但是写请求会转发给主节点,该节点的引入为zookeeper集群提供了更强力的伸缩性和高吞吐量,提升健壮性(多从节点的投票会导致延迟骤增)。
1.4 集群模式
集群中的模式分为两种
- 崩溃恢复模式:主节点崩溃或者网络原因导致失去了与半数从节点的联系后,进入崩溃恢复模式,该模式下集群会选出一个新的主节点。
- 消息广播模式:两端提交过程,针对客户端的事务请求,主节点生成对应的事务提议号发送给其他节点并收集选票(只需收集到半数以上的节点反馈即可),最后进行事务提交。
1.5 节点选举流程
文章目录 |
---|
理解zookeeper选举机制 - 帅LOVE俊 - 博客园 (cnblogs.com) |
1.6 Zab协议
在上述的集群角色模式及选举中,遵循的都是约定的Zookeeper Atomic Broadcast原子广播协议,通过该协议保证分布式事务的最终一致性。
文章目录 |
---|
【Zookeeper】–ZAB (Zookeeper Atomic Broadcast)协议_全力奔跑,梦在彼岸-CSDN博客 |
Zab协议 (史上最全) - 疯狂创客圈 - 博客园 (cnblogs.com) |
1.7 ZXID
事务ID,是一个64位的数字,低32代表一个单调递增的计数器,高32位代表Leader周期。
其他相关联的文件:
- acceptedEpoch:follower已经接受leader更改Epoch的提议;
- currentEpoch:当前的Epoch
- history:当前节点接受到事务提议的log
- lastZxid:history中最近接收到的提议zxid(最大值)
- snapshot:快照版本
在数据目录中可以找到Epoch相关文件
只不过其它文件我没找到就是了…百度吧…
二、进阶玩法
经过上面的了解,应该对Zookeeper有了基本的认识,下面进行实操打码。
2.1 客户端的使用
使用bin目录下的zkCli.sh连接zookeeper
sh zkCli.sh -server 127.0.0.1:2191
连接后情况如下
![](https://csdn-pic-1301850093.cos.ap-guangzhou.myqcloud.com/csdn-pic/zookeeper使用内置客户端连接-1.png)
我们可以使用stat命令用于查看节点的状态信息,例如
stat命令结果解释
名称 | 作用 |
---|---|
cZxid | 节点创建时的cZxid |
ctime | 节点创建时间 |
mZxid | 节点最近一次更新时的zxid |
mtime | 节点最近一次更新的时间 |
cversion | 子节点数据更新次数 |
dataVersion | 本节点数据更新次数 |
aclVersion | 节点ACL(授权信息)的更新次数 |
ephemeralOwner | 如果该节点为临时节点,ephemeralOwner值表示与该节点绑定的session id。如果该节点不是临时节点,ephemeralOwner值为0 |
dataLength | 节点数据长度 |
numChildren | 子节点个数 |
客户端的基础命令
## 查看某个路径下目录列表
ls [path]
## 获取节点数据和状态信息,path:代表路径,[watch]:对节点进行事件监听
get path [watch]
## 查看节点状态信息
stat path [watch]
## create 命令用于创建节点并赋值
create [-s] [-e] path data acl
## 修改节点存储的数据
set path data [version]
## 删除某节点
delete path [version]
客户端命令进阶
四字命令 | 功能描述 |
---|---|
conf | 3.3.0版本引入的。打印出服务相关配置的详细信息。 |
cons | 3.3.0版本引入的。列出所有连接到这台服务器的客户端全部连接/会话详细信息。包括"接受/发送"的包数量、会话id、操作延迟、最后的操作执行等等信息。 |
crst | 3.3.0版本引入的。重置所有连接的连接和会话统计信息。 |
dump | 列出那些比较重要的会话和临时节点。这个命令只能在leader节点上有用。 |
envi | 打印出服务环境的详细信息。 |
reqs | 列出未经处理的请求 |
ruok | 测试服务是否处于正确状态。如果确实如此,那么服务返回"imok",否则不做任何相应。 |
stat | 输出关于性能和连接的客户端的列表。 |
srst | 重置服务器的统计。 |
srvr | 3.3.0版本引入的。列出连接服务器的详细信息 |
wchs | 3.3.0版本引入的。列出服务器watch的详细信息。 |
wchc | 3.3.0版本引入的。通过session列出服务器watch的详细信息,它的输出是一个与watch相关的会话的列表。 |
wchp | 3.3.0版本引入的。通过路径列出服务器watch的详细信息。它输出一个与session相关的路径。 |
mntr | 3.4.0版本引入的。输出可用于检测集群健康状态的变量列表 |
其他博主写的比我全多了
文章目录 |
---|
ZooKeeper 客户端命令 zkCli - 江湖小小白 - 博客园 (cnblogs.com) |
zookeeper客户端命令详解 - 木易森林 - 博客园 (cnblogs.com) |
2.2 可视化管理工具
市面上能找到的对zookeeper节点可视化的工具蛮少的,我试试下面两款,一个是C/S,一个是B/S。
ZooViewer
客户端形式的可视化工具
文章目录 |
---|
GitHub - javaquery/zooviewer: Automatically exported from code.google.com/p/zooviewer |
很简单,根据源码地址把文件拉到本地,双击Run.bat
启动,输入完地址及端口号后,将出现如下界面
对客户端具体的使用还得看后面我们进行开发的时候去查看节点数据。
Zkui
Web界面的可视化工具
文章目录 |
---|
GitHub - DeemOpen/zkui: A UI dashboard that allows CRUD operations on Zookeeper. |
2.3 ZkClient开发实战
文章目录 |
---|
Zookeeper基础(三):Zookeeper客户端ZkClient - 简书 (jianshu.com) |
2.4 Curator应用开发实战
第一步,永远都是先引入依赖
<!-- 对zookeeper的底层api的一些封装 -->
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>5.2.0</version>
</dependency>
<!-- 封装了一些高级特性,如:Cache事件监听、选举、分布式锁、分布式Barrier -->
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<version>5.2.0</version>
</dependency>
DEMO
import org.apache.curator.RetryPolicy;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.apache.zookeeper.data.Stat;
/**
* @author 李家民
*/
public class DemoApplication {
public static void main(String[] args) throws Exception {
// RetryPolicy重试策略
RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 3);
// 流式风格构建
CuratorFramework client = CuratorFrameworkFactory.builder()
.connectString("127.0.0.1:2191")
.sessionTimeoutMs(10000)
.connectionTimeoutMs(50000)
.retryPolicy(retryPolicy)
.namespace("zookeeper_demo")
.build();
client.start();
// 查看连接状态
System.out.println(client.getState());
// 创建一个永久节点
client.create().forPath("/curatorDemo", "/curator data Demo".getBytes());
// 测试检查某个节点是否存在
Stat stat1 = client.checkExists().forPath("/curatorDemo");
Stat stat2 = client.checkExists().forPath("/234234");
System.out.println("'/curatorDemo'是否存在: " + (stat1 != null ? true : false));
System.out.println("'/234234'是否存在: " + (stat2 != null ? true :