一、Zookeeper 基础知识
1、什么是Zookeeper
通俗解释: Zookeeper 是一个“协调者”,用来帮助多台服务器一起配合工作、保持信息一致。提供分布式协调服务
类比: 像一个班级的“班长”,不负责做作业,但负责:
分配任务;
发现掉队的同学;
通知大家更新规则;
管理排队顺序。
2、Zookeeper 解决什么问题?
在大数据系统中,有很多机器同时运行,问题是:
遇到的问题 举例 谁是“领导者”? 多台 NameNode 哪台说了算? 配置要统一吗? 每台机器的参数设置是否一样? 同时操作怎么办? 多个服务一起操作订单,会不会重复扣款? 节点宕机怎么办? 某台机器突然挂了,谁来替它干活?
Zookeeper 就来解决这些“协调与一致性”的问题。
3、Zookeeper 的四大功能(用生活类比记忆)
功能名称 通俗解释 类比方式 典型应用场景(真实用法) 命名服务 给每台服务器或服务取个独一无二的名字 像微信昵称、QQ备注 ✔ Hadoop 集群中:每个 DataNode 启动时在 Zookeeper 的 /datanodes/ 路径下注册自己的临时节点,NameNode 能快速识别和定位所有存活节点。配置管理 所有服务器共享一份“设置文件” 像游戏里所有玩家统一分辨率、音量设置 ✔ Kafka 集群中:所有 broker 的配置(如分区副本数量、副本同步策略等)通过 Zookeeper 统一管理。✔ 大数据平台参数配置:比如所有节点统一使用 /config/hdfs-site.xml 配置项,改一次全同步。分布式锁 同一时刻只允许一个节点操作关键资源,防止冲突 像银行叫号、打饭排队 ✔ 电商订单处理系统:多个服务器同时接收订单请求,只有拿到 /order_locks/123 锁的节点才允许处理该订单,避免重复扣款或重复发货。✔ 定时任务抢占执行权:多个实例争抢定时任务执行,谁拿到锁谁执行,防止多次执行。节点管理 实时监控每台服务器的在线/离线状态 像游戏里的“谁在线”列表 ✔ HDFS NameNode 高可用(HA):Zookeeper 检测到 Active NameNode 宕机,自动切换到 Standby 节点。✔ Flink/YARN 集群:检测 TaskManager 或 NodeManager 节点的上下线,动态调整资源分配。
4、Zookeeper 的核心数据结构:znode
znode 是什么? Zookeeper 把所有信息存在一棵“树”里,树上的每个“节点”叫 znode,就像操作系统的“文件夹”。
znode 节点结构设计(对应四大核心功能)
/ # 根目录
├── config/ # 配置管理(功能2) → 统一的配置中心
│ ├── hdfs-site.xml
│ └── kafka-broker.properties
├── datanodes/ # 命名服务(功能1) → 每个节点在这注册
│ ├── 192.168.1.101 # DataNode A(临时节点)
│ ├── 192.168.1.102 # DataNode B(临时节点)
│ └── 192.168.1.103 # DataNode C(临时节点)
├── order_locks/ # 分布式锁(功能3) → 控制订单抢占
│ ├── 123 # 订单编号为123的锁,谁创建成功谁处理订单
├── leader/ # 节点管理(功能4) → 记录主节点
│ └── active_namenode # 当前的 Active NameNode 节点地址
路径 对应功能 用法说明 /config/配置管理 所有服务共享配置 /datanodes/命名服务 注册服务器IP,临时节点形式 /order_locks/分布式锁 加锁资源控制并发访问 /leader/节点管理 记录主节点,实现故障切换
Zookeeper 的四大功能互动类比目录
1️⃣ 命名服务(Name Service)
你是 DataNode,启动时你会在
/datanodes/注册自己,就像在微信群里发个“我在”。 大家就能知道你上线了,NameNode 才能找到你是谁,在哪儿。2️⃣ 配置管理(Configuration Management)
你是 Kafka 中的一个 Broker,启动前你得先看看
/config里的参数,就像游戏开局前统一设置好分辨率和音量。 所有服务器都读同一份配置,改一次全员同步,省得你一个个去调。3️⃣ 分布式锁(Distributed Lock)
订单123需要加锁,只有抢到
/order_locks/123这个“钥匙”的服务器才有权限处理,就像打饭排队拿号一样。 先到先处理,后来的乖乖等着,避免多个服务重复发货。4️⃣ 节点管理(Online Node Monitoring)
你是 TaskManager,上线时在
/nodes/发了“我在”,Zookeeper 就知道你活着。 一旦你断网,它立刻告诉系统“他掉线了”,就像游戏中的“谁还在线”状态栏。
5、znode 有哪些类型?(四种)
类型 特点说明 应用场景 类比记忆 持久节点 永久存在,除非手动删除 存放配置信息、服务注册 像手动保存的文件夹 持久顺序节点 永久存在 + 自动编号 排队创建任务(如 /task-000001) 像生成工单号的排队机 临时节点 客户端断开连接后自动删除 表示某个服务是否在线 像微信在线状态 临时顺序节点 自动编号 + 断开就删 实现分布式锁的排队逻辑 像食堂排队打饭且掉队就退出
口诀记忆:
持久不怕断,临时断就删;
加号是编号,排队靠得安。
6、Zookeeper 的三种角色(分工明确)
角色 职责说明 类比说明 典型应用场景 Leader 负责所有 写操作,发号施令,协调同步 班长,统一指挥 ✔ 在 NameNode 高可用场景中,只有 Leader 负责写入元数据,并同步给所有 Follower Follower 负责处理 读请求,也参与 选举投票,同步数据 班委,听指挥也能投票 ✔ 当 Leader 宕机,Follower 会参与新 Leader 的选举;也能回应客户端读请求 Observer 不参与投票和写确认,只负责 读取和减轻压力 旁听生,看但不决定 ✔ 在 大型 Kafka 集群中增加 Observer 节点,专门处理只读查询,提高性能
实际案例讲解:电商订单加锁,三个角色怎么配合?
背景设定: 你有一个电商系统,有很多服务器可能同时处理同一个订单,比如订单123,如果都一起操作,就会重复扣款或重复发货,非常危险!
所以我们用 Zookeeper 来管住这个“抢订单”的过程。
👨🏫 三个角色的分工(像班级管理)
角色 负责干嘛? 像谁? Leader(领导) 做决定:谁能处理订单?谁先谁后? 像班长 Follower(跟班) 跟着 Leader 一起记账,也能回答简单问题 像班委 Observer(旁观) 不投票不下命令,只回答查询类问题,帮忙减压 像旁听生、帮忙查资料
为什么要这么分工?
Leader 专注处理“谁先谁后”的大事,效率高。
Follower 备份数据,防止 Leader 坏掉时接替。
Observer 只读不写,帮忙回答问题,减轻压力。
场景:订单加锁怎么实现?
问题: 多个服务器同时想处理订单 123,谁来决定谁先上?
Zookeeper 加锁的办法:
服务器 A 想抢订单,会去 Zookeeper 里创建一个小节点,比如
/order_locks/123;如果这个节点还没被别人抢走,A 就成功拿到这个订单的处理权;
A 处理完后,删除这个锁节点;
后面的服务器继续排队,等锁释放,再去抢。
生活类比:银行叫号系统
拿号排队:谁先拿号,谁先服务;
处理完了,系统才叫下一个;
防止一堆人冲进去,乱成一团。
记忆口诀(总结):
Leader 说了算,Follower 做保障,Observer 来分担; 抢订单像叫号,谁先拿号谁先干。
7、Zookeeper 在 Hadoop 中的作用(NameNode 高可用 )
NameNode 高可用(NameNode HA) 是指在 Hadoop 集群中部署 两个 NameNode(一个主用、一个备用),确保当主 NameNode 宕机时,系统可以自动切换到备用 NameNode,不中断服务、保障数据访问正常。
✅ 简要解释:
目的:解决 Hadoop 单点故障问题(原来只有一个 NameNode,挂了就全瘫)。
组成:
Active NameNode:正在工作的主节点。
Standby NameNode:备用节点,实时同步数据,随时准备接管。
Zookeeper:监控 NameNode 状态,自动完成主备切换。
效果:即使主 NameNode 宕机,也能快速切换,继续访问 HDFS 文件系统。
问题 Zookeeper 的作用 主 NameNode 掉线怎么办? Zookeeper 自动检测并让备用 NameNode 顶上 节点动态加入/下线怎么办? 创建/删除 znode 表示在线状态,Zookeeper 自动感知并通知
8、Zookeeper 与 YARN 区别
对比点 Zookeeper YARN 主要作用 协调、保持一致性 资源分配、任务调度 管什么 谁是 Leader,配置一致,排队锁等 哪个节点执行哪个任务,用多少内存/CPU 是否直接关联? 一些高级 Hadoop 场景才用(如 HA) Hadoop 默认核心模块
二、搭建zookeeper分布式集群
1、环境要求:
已搭建好的Hadoop完全分布式集群(三台主机master;slave1;slave2)
2、前期准备
2.1 关闭防火墙
三台主机都要关闭防火墙【我们的集群已设置关闭】!!!
2.2 准备软件
官网下载地址:https://archive.apache.org/dist/zookeeper/
本教程使用版本:
apache-zookeeper-3.5.7-bin.tar.gz
3、配置zookeeper
3.1 解压安装包
将下载的apache-zookeeper-3.5.7-bin.tar.gz,移动到master主机/opt/software下。
# 在master主机操作
cd /opt/software
# 把Zookeeper压缩包解压到/opt/apps目录下并重命名
tar -zxvf apache-zookeeper-3.5.7-bin.tar.gz -C /opt/apps
cd /opt/apps
mv apache-zookeeper-3.5.7-bin zookeeper
3.2 创建数据和日志存放的目录
cd /opt/apps/zookeeper
mkdir data # 用于存放ZooKeeper内存数据库的快照数据(持久化内存状态)
mkdir log # 用于存放ZooKeeper的事务日志文件(记录每次数据变更的日志)
3.3 修改配置文件
第一步:复制配置模板
进入配置文件目录:
cd /opt/apps/zookeeper/conf
将默认模板文件 zoo_sample.cfg 复制为正式配置文件 zoo.cfg:
cp zoo_sample.cfg zoo.cfg
第二步:编辑配置文件
使用文本编辑器打开 zoo.cfg 文件:
vi zoo.cfg
修改以下几个关键配置项
# The number of milliseconds of each tick
tickTime=2000
# The number of ticks that the initial
# synchronization phase can take
initLimit=10
# The number of ticks that can pass between
# sending a request and getting an acknowledgement
syncLimit=5
# the directory where the snapshot is stored.
# do not use /tmp for storage, /tmp here is just
# example sakes.
# 设置存储快照文件数据目录和事务日志目录
dataDir=/opt/apps/zookeeper/data
dataLogDir=/opt/apps/zookeeper/log
# 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
# server.1=master:2888(数据同步端口):3888(Leader选举端口)
server.1=master:2888:3888
server.2=slave1:2888:3888
server.3=slave2:2888:3888
解释:
tickTime(心跳时间基准单位):
作用:ZooKeeper 服务器之间或服务器与客户端之间交互的基本时间单元,控制心跳频率。
默认值:2000 毫秒(即 2 秒)
示例:Leader 每 2 秒给 Follower 发一次心跳,客户端也每 2 秒确认一次是否在线。
initLimit(连接初始化最大等待时间):
作用:Follower 启动时最多等待多少个 tickTime 时间与 Leader 建立连接。
默认值:10(表示最多等 10 × 2 = 20 秒)
示例:Follower 启动慢,只要 20 秒内连上 Leader 就算正常。
syncLimit(数据同步最大等待时间):
作用:Follower 同步数据时,最多能“掉线”多少个 tickTime 时间。
默认值:5(表示最多等 10 秒)
示例:如果 10 秒内 Follower 没回应,Leader 认为它故障。
dataDir(数据存储目录):
作用:存放 Zookeeper 的数据文件(如 myid、快照等)
建议值:
/opt/apps/zookeeper/data
dataLogDir(事务日志路径):
作用:存放 Zookeeper 的事务日志(如果不写,默认与
dataDir相同)
clientPort(客户端连接端口):
作用:客户端连接 Zookeeper 时使用的端口号
默认值:2181
Zookeeper 客户端程序(如 Kafka、Hadoop、Flink、写的 Java 程序等)连接 Zookeeper 服务器所用的端口号。
server.A=B:C:D(集群服务器配置):
A:服务器编号(与每台机的myid文件内容一致)
B:服务器的 IP 地址
C:用于 Leader 与 Follower 之间同步数据的端口
D:用于 Leader 选举的端口作用:定义集群中每台服务器的通信方式
含义说明:
3.4 创建服务器myid编号
配置目的:
Zookeeper 集群要求每台服务器都有一个唯一编号,用于区分不同节点。
这个编号要写入
dataDir目录下的myid文件,且必须和配置文件中的server.x中的x一致。
# 操作步骤(以 master 节点为例): cd /opt/apps/zookeeper/data # 方法一:使用 vi 编辑器创建 vi myid # 输入数字 1(表示当前节点编号为1) # 注意:上下不要有空行,左右不要有空格 # 方法二:使用 touch 创建文件,再编辑 touch myid # 再使用编辑器打开,输入数字 1,保存退出
3.5 集群目录拷贝
为了在其他节点复用 Zookeeper 的安装与配置,需要将已配置好的目录从主节点(master)拷贝到 slave1 和 slave2。
scp -r /opt/apps/zookeeper root@slave1:/opt/apps scp -r /opt/apps/zookeeper root@slave2:/opt/apps
3.6 集群myid更改
分别进入到slave1、slave2节点,修改各节点的
myid值和上述服务中的server.x对应
# 进入slave1 cd /opt/apps/zookeeper/data vi myid #修改为 2 # 进入slave2 cd /opt/apps/zookeeper/data vi myid #修改为 3
3.7 集群环境变量添加
为方便在任何目录下直接使用
zkServer.sh、zkCli.sh等命令,我们需要为 ZooKeeper 添加环境变量。
1.配置 master 节点环境变量
# 在 master 节点上,编辑环境变量配置文件 vi /etc/profile
在文件末尾添加以下内容,配置 ZooKeeper 的环境变量:
# ZOOKEEPER 安装路径 export ZOOKEEPER_HOME=/opt/apps/zookeeper export PATH=$PATH:$ZOOKEEPER_HOME/bin
保存并退出,然后使配置立即生效:
source /etc/profile
2.把master上的profile配置文件分发到其余两台主机
scp /etc/profile root@slave1:/etc/ scp /etc/profile root@slave2:/etc/
3.分别在slave1、slave2下运行命令使环境变量生效:
source /etc/profile
3.8 集群启动
依次在
master、slave1、slave2启动集群建议启动的时候要先启动
master,否则会报错。(根据myid从小到大的顺序启动)如果启动失败,请停止集群:
zkServer.sh stop,参考3.10问题解决的方案进行检查
# 1.在master、slave1、slave2依次启动ZK集群 zkServer.sh start
# 2.在master、slave1、slave2依次查看ZK状态 zkServer.sh status
【如正常启动,会看到下方图示的界面】
master节点:

slave1节点:

slave2节点:

从截图中可以看到,slave1服务器成为了leader主节点,其余为follower从节点
使用命令jps查看三台主机的进程:
出现
QuorumPeerMain则说明zookeeper启动成功

QuorumPeerMain 是 ZooKeeper 集群模式的启动程序,用于启动和管理多个 ZooKeeper 服务器节点,实现分布式应用程序的协调工作。
quorum /kwɔːrəm/ 法定人数,定额peer /pɪə/ 对等
分布式zookeeper集群搭建完毕!
3.9 集群关闭
zkServer.sh stop # 停止ZK服务
# zkServer.sh restart # 重启ZK服务
3.10 问题排查与解决总结
⚠ 如果 ZooKeeper 集群无法启动或某节点异常,请逐项检查以下内容:
1、防火墙状态
三台主机务必关闭防火墙,避免端口通信被拦截。
否则可能报错:
没有到主机的路由(No route to host)。
2、主机名与域名解析
检查
/etc/hosts中的域名解析配置是否正确;每台主机都能解析集群中其他主机的 IP 和主机名。
3、myid 编号是否与配置一致
dataDir下的myid编号必须与zoo.cfg中的server.x中的x一一对应;不一致会导致无法加入集群。
4、日志与数据目录是否存在
检查配置中的
dataDir和(可选的)dataLogDir目录是否存在;若不存在需手动创建,避免服务启动失败。
5、检查 zoo.cfg 配置
是否误删关键配置项;
各
server.x=B:C:D是否配置正确;clientPort是否冲突等。
6、启动方式建议使用前台查看日志
后台启动(安静模式):
zkServer.sh start
推荐方式:前台启动,便于查看错误日志
zkServer.sh start-foreground
日志默认位置:
/opt/apps/zookeeper/logs/zookeeper-root-server-主机名.out
7、查看端口是否占用(默认:2181)
# 查看端口和连接的信息,获取进程名、进程号以及用户 ID
netstat -tunlp | grep 2181
# 若端口已被占用,可先杀掉对应进程再重启
kill -9 13567
zkServer.sh start-foreground # 前台启动
zkServer.sh restart # 再次启动
# 知识点:
2181:对cline端提供服务
3888:选举leader使用
2888:集群内机器通讯使用(Leader监听此端口)

8、更换 myid 编号重启(极端情况)
如果某主机始终无法启动,尝试更改其
myid值;原因:可能是上次非正常关机,产生了残留元数据;
更换编号后会自动重新生成新的文件,可能恢复正常。
记录坑点:某次调试过程中,三台机器均配置无误,但 master 主机 ZooKeeper 无法启动,重装无效。后将其 myid 从 1 改为 4,问题立刻解决。
3.11 ZooKeeper 集群节点同步实验
实验目标
在
master节点创建一个 znode;在
slave1和slave2上验证是否同步;演示 znode 数据的修改、监听与删除过程;
证明 ZooKeeper 集群数据的一致性与同步性。
实验步骤
# 1.在master上启动ZooKeeper客户端,连接到master节点的ZooKeeper服务器。
zkCli.sh -server master:2181
# 运行结果:出现下面的客户端命令行提示符
[zk: master:2181(CONNECTED) 0] # 客户端命令行提示符,0表示会话ID
# 2.查看根节点内容
[zk: master:2181(CONNECTED) 0] ls / # /是根节点 ,zookeeper是子节点
# 运行结果:仅看到系统默认的 zookeeper 子节点
[zookeeper]
# 3.创建一个新的Znode节点"data",并存储数据 "Hello, ZooKeeper!"
[zk: master:2181(CONNECTED) 1] create /data "Hello, ZooKeeper!"
# 运行结果:
Created /data
# 4.查看根节点内容
[zk: master:2181(CONNECTED) 2] ls /
# 运行结果:
[data, zookeeper]
# 5.使用get命令查看data节点中的字符串
[zk: master:2181(CONNECTED) 3] get /data
# 运行结果:
"Hello, ZooKeeper!"
# 6.在slave1主机上登录slave1节点的客户端
zkCli.sh -server slave1:2181
# 7.使用ls命令查看当前Zookeeper中所包含的内容
[zk: slave1:2181(CONNECTED) 0] ls /
# 可以查看到我们在master节点上创建的znode,代表集群中的节点能够正常同步数据
[data, zookeeper]
# 使用get命令查看data节点中的信息
[zk: slave1:2181(CONNECTED) 1] get /data # 查看数据也是一致的
"Hello, ZooKeeper!"
# 8.在slave2主机上登录slave2节点的客户端
zkCli.sh -server slave2:2181
# 也能查看到我们在master节点上创建的znode
[zk: slave2:2181(CONNECTED) 0] ls /
# 也可以查看到在master节点上创建的znode
[data, zookeeper]
# 使用get命令查看data节点中的信息
[zk: slave2:2181(CONNECTED) 1] get /data # 数据也是一致的
"Hello, ZooKeeper!"
# 9.在slave2的zookeeper的客户端修改/data节点的数据内容
[zk: slave2:2181(CONNECTED) 2] set /data "hi zookeeper!"
# 10.在master的zookeeper的客户端使用get命令查看data节点中的字符串
[zk: master:2181(CONNECTED) 3] get /data
# 运行结果
"hi zookeeper!"
# 11.在master的zookeeper的客户端使用get -w命令查看data节点中的字符串,并监听该节点的数据变化
[zk: master:2181(CONNECTED) 3] get -w /data
"hi zookeeper!"
# 12.在slave2的zookeeper的客户端修改/data节点的数据内容
[zk: slave2:2181(CONNECTED) 3] set /data "hi zookeeper,666!"
# 13.在master的zookeeper的客户端显示监听到了path:/data节点的数据发生了改变
[zk: master:2181(CONNECTED) 7]
WATCHER::
WatchedEvent state:SyncConnected type:NodeDataChanged path:/data
# 14.删除节点
[zk: master:2181(CONNECTED) 8] delete /data
# 15.退出
[zk: localhost:2183(CONNECTED) 1] quit
实验结论
ZooKeeper 是一个分布式协调系统;
在任一节点创建的 znode 都能实时同步到整个集群;
修改、监听、删除等操作都能保持强一致性;
实验验证了 ZooKeeper 数据同步和观察者机制的基本原理。
3.12 测试 ZooKeeper 集群角色切换与 Leader 选举机制
实验目标
理解 ZooKeeper 集群中的三种角色(Leader、Follower、Observer);
掌握 ZooKeeper 的自动 Leader 选举机制;
验证当 Leader 挂掉后,其他节点是否能自动选出新的 Leader;
验证挂掉的节点重启后是否以 Follower 身份加入集群。
实验步骤
步骤 1:查看当前集群中的角色状态
在 3 台机器中任意执行 zkServer.sh status 查看角色(以 slave1 为例):
[hadoop@slave1 ~]$ zkServer.sh status
运行结果(示例):
ZooKeeper JMX enabled by default Using config: /usr/local/zookeeper/conf/zoo.cfg Mode: leader
✅ 当前节点 slave1 是 Leader。
步骤 2:关闭 Leader 节点的 ZooKeeper 服务
[hadoop@slave1 ~]$ zkServer.sh stop
运行结果:
Stopping zookeeper ... STOPPED
步骤 3:在其他节点查看角色变化情况
[hadoop@slave2 ~]$ zkServer.sh status
[hadoop@master ~]$ zkServer.sh status
示例输出:
slave2: Mode: leader
master: Mode: follower
✅ slave2 成为新的 Leader,master 是 Follower。
步骤 4:重启被关闭的节点(原 Leader)
[hadoop@slave1 ~]$ zkServer.sh start
[hadoop@slave1 ~]$ zkServer.sh status
输出:
Mode: follower
✅ slave1 加入集群后为 Follower,未重新获得 Leader 身份。
实验现象总结
节点 初始角色 停止后角色变化 重启后角色 slave1 Leader 已停止 Follower slave2 Follower 升为 Leader Leader master Follower 不变 Follower
实验结论
ZooKeeper 是一个分布式一致性协调服务,具备自动 Leader 选举机制;
只有在 Leader 节点挂掉时,才会重新触发选举过程;
新加入(或重启)的节点会以 Follower 身份加入,不会自动成为 Leader;
集群中始终保持一个 Leader 和若干 Follower,保障系统的一致性与稳定性。
三、常用命令
创建节点:使用
create命令可以在指定路径下创建一个节点,并设置节点的数据内容。例如:create /testNode "Hello World"。查看节点数据:使用
get命令可以获取指定节点的数据内容。例如:get /testNode。修改节点数据:使用
set命令可以修改指定节点的数据内容。例如:set /testNode "New Data"。删除节点:使用
delete命令可以删除指定节点及其子节点。例如:delete /testNode。查看子节点列表:使用
ls命令可以查看指定节点下的子节点列表。例如:ls /。监听节点变化:使用
get命令时加上-w参数,可以监听指定节点的数据变化。例如:get -w /testNode。监听子节点变化:使用
ls命令时加上-w参数,可以监听指定节点下子节点的变化。例如:ls -w /。递归删除节点:使用
deleteall命令可以递归删除指定节点及其子节点。例如:deleteall /testNode。
四、实验
实验1:通过文件实现 ZooKeeper 通知机制
实验目标:
通过创建和修改 ZooKeeper 节点的数据,学习如何利用 ZooKeeper 的通知机制来监听节点和子节点的变化,模拟文件修改通知的机制。
实验环境:
ZooKeeper 已安装并运行。
Hadoop 集群有多个节点(
master、slave1、slave2),并通过 ZooKeeper 进行协调。通过 ZooKeeper 客户端
zkCli.sh在各个节点(master、slave1、slave2)执行操作。zkCli.sh是 ZooKeeper 提供的命令行客户端工具,用于与 ZooKeeper 服务器进行交互
实验步骤:
步骤 1:启动 ZooKeeper 客户端
# 分别在master\slave1\slave2上执行操作
zkCli.sh
注意:以下的操作是在ZooKeeper 客户端的命令行下进行操作
步骤 2:创建节点
create /cookie "大盘鸡"
# ZooKeeper中的每一个节点都称为znode。这些znodes可以存储数据,也可以作为父节点包含子节点
步骤 3:查看节点数据
# 在master/slave1/slave2上分别操作,都可以看到信息
get /cookie
步骤 4:修改节点数据
# 在slave1上进行修改节点数据 set /cookie "手抓饭" # 在master/slave1/slave2上分别操作,都可以看到修改后的信息 get /cookie
步骤 5:监听节点变化
# 在 master 节点上执行, 通过 `get -w` 监听 `master` 节点上的 `/cookie` 节点变化。 get -w /cookie
通过 get -w 监听 master 节点上的 /cookie 节点变化。
# 在 slave2 上执行修改节点信息 set /cookie "烤全羊"
观察 master 节点上监听的输出。
WATCHER:: WatchedEvent state:SyncConnected type:NodeDataChanged path:/cookie # 表示 ZooKeeper 监控到 /cookie 节点的数据发生了变化,并通知客户端当前与服务器连接正常 # (SyncConnected 状态)。
步骤 6:创建子节点并监听子节点变化
# 在 master 节点上执行 ls -w /cookie
使用 ls -w 监听 master 节点上 / 目录下的子节点变化。
# 在 slave2 上执行 create /cookie/drink "奶茶"
观察 master 节点上监听的输出。
步骤 7:删除节点并触发通知
# 在 slave1上执行,依次删除节点 delete /cookie/drink delete /cookie # 或者递归删除 deleteall /cookie
观察 master 节点上的监听输出。
实验总结:
通过模拟实验,将学习如何使用 ZooKeeper 的命令创建和修改节点,并通过监听机制实时获取节点或子节点的变化通知。这种机制类似于分布式系统中的协调和通知功能,像是在文件系统中对文件变化的监控。
实验2:通过 ZooKeeper 实现集群管理
实验目标:
通过创建和删除 ZooKeeper 节点,模拟分布式集群中的节点管理。实现节点的注册、心跳检测、故障感知等集群管理功能,模拟集群中的节点加入和退出。
实验环境:
ZooKeeper 已安装并启动。
Hadoop 集群有多个节点(
master、slave1、slave2),并通过 ZooKeeper 进行协调。分别在master\slave1\slave2上执行操作
zkCli.sh启动ZooKeeper客户端。
实验步骤:
注意:以下的操作是在ZooKeeper 客户端的命令行下进行操作
步骤 1:模拟节点注册(节点加入集群)
在 ZooKeeper 中,每个节点在启动时,会在 ZooKeeper 上注册一个临时节点,表示该节点已加入集群。我们通过在 /cluster/ 下创建临时节点,模拟集群中的节点注册。
# 在 slave1 上执行,先创建父节点,再注册一个临时节点 create /cluster create -e /cluster/slave1 "slave1 active" # -e:表示创建的是临时节点,节点会在客户端断开连接时自动删除。
-e参数表示创建临时节点,如果slave1断开连接,ZooKeeper 会自动删除这个节点。
# 在 slave2上执行,先创建父节点【可以省略】,再注册一个临时节点 create /cluster create -e /cluster/slave2 "slave2 active"
步骤 2:监听节点状态变化(监控节点)
在 master 节点上,通过监听 /cluster 目录下的节点变化,可以实时监控集群中节点的加入或失效。
# 在 master 上执行,监听所有集群节点的状态变化
ls -w /cluster
步骤 3:模拟节点故障(节点离开集群)
在分布式系统中,节点可能因为网络故障或宕机而退出集群。当 ZooKeeper 中的临时节点被删除时,表示节点失效。在本实验中,可以通过手动删除节点或关闭连接来模拟节点故障。
# 在 slave1 上执行,删除节点以模拟节点故障
delete /cluster/slave1
观察 master 节点上监听的输出,ZooKeeper 会通知 master,节点 /cluster/slave1 已失效。
步骤 4:模拟节点心跳检测(节点自动失效)
ZooKeeper 的临时节点特性可以自动管理节点的连接状态。当某个节点与 ZooKeeper 断开连接时,ZooKeeper 会自动删除该节点的临时节点。你可以通过关闭 zkCli.sh 来模拟这种情况:
# 在 slave2 上断开连接(关闭 zkCli.sh), 或者按下ctrl + C
quit
观察 master 上的输出,/cluster/slave2 节点会自动被删除,表示节点已失效。
步骤 5:节点恢复(重新加入集群)
如果一个失效的节点重新连接到集群,它可以再次注册到 ZooKeeper。此时,集群中的其他节点将收到新的节点加入的通知。
# 重新启动 slave2 上的 zkCli.sh 并注册节点
zkCli.sh
create -e /cluster/slave2 "slave2 active"
实验总结:
通过此实验,ZooKeeper 通过临时节点和Watcher 机制实现了集群管理功能,能够监控分布式系统中节点的加入【命名服务】和退出、故障检测、节点恢复等。ZooKeeper 在分布式集群管理中,可以确保集群的高可用性和动态扩展。
实验3:使用 ZooKeeper 实现简单的分布式锁
实验目标:
通过这个实验,你将学会如何使用 ZooKeeper 来模拟分布式系统中的锁机制,让多个节点按顺序访问共享资源。这样可以保证每次只有一个节点能够执行任务,避免冲突。
实验环境:
ZooKeeper 已安装并运行。
有三个节点(
master、slave1、slave2)。使用 ZooKeeper 命令行客户端
zkCli.sh来操作。
注意:以下的操作是在ZooKeeper 客户端的命令行下进行操作
实验步骤:
步骤 1:创建用于锁的目录
首先,我们需要创建一个专门用来管理“锁”的目录。在这个目录中,所有节点都会争夺锁。
在
master节点上运行:create /locks
这会创建一个叫
/locks的目录,所有节点将会在这里争夺锁。
步骤 2:节点争夺锁
每个节点想要获得锁时,会在 /locks 目录下创建一个临时且有序的节点。ZooKeeper 会为每个节点分配一个带编号的节点,谁的编号最小,谁就拿到锁。
在
slave1上执行:create -e -s /locks/lock_ "slave1 requests lock"
# -e:表示创建的是临时节点,节点会在客户端断开连接时自动删除。
# -s:表示创建的是有序节点,ZooKeeper 会在节点名称后自动加上递增的序号。
# 这会创建一个类似于 /locks/lock_0000000000 的节点,用来标识slave1。【这也是命名服务】这会创建一个像
/locks/lock_00000000这样的节点。在
slave2上执行:create -e -s /locks/lock_ "slave2 requests lock"
这会创建一个像
/locks/lock_0000000001这样的节点。
步骤 3:谁拿到锁?
ZooKeeper 会根据节点编号来决定谁拿到锁,编号最小的节点获胜。
在
slave1和slave2上运行以下命令来查看锁的状态:ls /locks
假设输出为:
[lock_0000000000, lock_0000000001]
slave1创建的节点是lock_0000000000,它的编号最小,因此它获得锁。slave2必须等待,因为它的节点是lock_0000000001。
步骤 4:slave2 监听锁的释放
当 slave1 完成任务并释放锁时,slave2 需要监听并等待锁的释放。我们可以让 slave2 监听 slave1 的节点。
在
slave2上监听slave1的节点(即lock_0000000000):get -w /locks/lock_0000000000
步骤 5:slave1 释放锁
slave1 完成任务后,会删除它的节点,表示它释放了锁。
在
slave1上执行:delete /locks/lock_0000000000
这样,
slave1就释放了锁。
步骤 6:slave2 获取锁的通知
当 slave1 删除节点时,slave2 会收到通知,它现在可以继续执行任务了。
slave2会显示以下内容,表示它现在可以继续:WATCHER::
WatchedEvent state:SyncConnected type:NodeDeleted path:/locks/lock_00000000此时
slave2获得锁并可以执行任务。
步骤 7:验证锁状态
在
slave2上运行:ls /locks
如果输出为:
[lock_0000000001]
说明
slave2已经获得了锁,现在可以执行任务。
总结:
每个节点通过在
/locks目录下创建有序临时节点争夺锁,编号最小的节点获得锁。如果没有拿到锁,节点会监听前一个节点的删除事件,直到轮到自己为止。