大数据-28 ZooKeeper集群 ZNode 数据结构与监听机制 Watcher机制

97 阅读10分钟

点一下关注吧!!!非常感谢!!持续更新!!!

🚀 AI篇持续更新中!(长期更新)

AI炼丹日志-29 - 字节跳动 DeerFlow 深度研究框斜体样式架 私有部署 测试上手 架构研究,持续打造实用AI工具指南!📐🤖

💻 Java篇正式开启!(300篇)

目前2025年07月02日更新到: Java-61 深入浅出 分布式服务 一致性算法 Raft 多图详解 MyBatis 已完结,Spring 已完结,Nginx已完结,Tomcat已完结,分布式服务正在更新!深入浅出助你打牢基础!

📊 大数据板块已完成多项干货更新(300篇):

包括 Hadoop、Hive、Kafka、Flink、ClickHouse、Elasticsearch 等二十余项核心组件,覆盖离线+实时数仓全栈! 大数据-278 Spark MLib - 基础介绍 机器学习算法 梯度提升树 GBDT案例 详解

在这里插入图片描述

章节内容

上节我们完成了:

  • ZooKeeper 集群配置
  • ZooKeeper 集群启动
  • ZooKeeper 集群状况查看
  • Follower 和 Leader 节点

背景介绍

这里是三台公网云服务器,每台 2C4G,搭建一个Hadoop的学习环境,供我学习。

  • 2C4G 编号 h121
  • 2C4G 编号 h122
  • 2C2G 编号 h123

在这里插入图片描述

ZooKeeper简介

核心特性

  1. 分布式一致性保证

    • 提供顺序一致性(所有更新请求按顺序执行)
    • 原子性(更新要么成功要么失败)
    • 单一系统镜像(无论连接到哪个服务器,客户端看到的数据视图都是一致的)
    • 可靠性(一旦更新被应用,将保持到被下一次更新覆盖)
    • 及时性(客户端在一定时间内能看到最新的数据)
  2. 数据模型

    • 本质上是一个分布式的小文件存储系统,采用类似Unix文件系统的树形层次结构(称为ZNode Tree)
    • 每个节点(ZNode)可以存储少量数据(默认上限1MB)
    • 节点分为持久节点(PERSISTENT)和临时节点(EPHEMERAL),后者在会话结束后自动删除
  3. 监控机制(Watcher)

    • 客户端可以注册监听特定节点的变化
    • 当节点数据变更或子节点列表变化时会触发通知
    • 采用一次触发机制,收到通知后需要重新注册

典型应用场景

  1. 统一命名服务

    • 如Dubbo服务注册中心,服务提供者将服务地址注册到ZooKeeper
    • 消费者从ZooKeeper获取可用的服务列表
    • 示例:/dubbo/com.example.Service/providers目录下存储服务提供者URL
  2. 分布式配置管理

    • 如Solr集群配置同步,所有节点监听配置节点
    • 配置变更时,管理员更新ZooKeeper上的配置数据
    • 各节点收到变更通知后自动获取新配置
    • 示例:/solr/configs/mycore目录存储核心配置
  3. 分布式消息队列

    • 实现发布/订阅模式(Pub/Sub)
    • 生产者创建顺序节点作为消息
    • 消费者监听父节点获取新消息
    • 示例:/queue/msg-0000000001,/queue/msg-0000000002
  4. 分布式锁

    • 实现互斥锁:多个客户端竞争创建同一个临时节点,成功创建的获得锁
    • 实现共享锁:通过节点顺序特性实现读写锁
    • 锁释放:会话结束自动删除临时节点或主动删除
  5. 集群管理

    • 监控集群节点存活状态(通过临时节点)
    • 选举主节点(通过节点序号最小的成为Master)
    • 示例:/cluster/node1(临时节点)自动消失表示节点下线

ZNode简介

在 ZooKeeper 中,所有数据都存储在树形结构的节点中,这些节点被称为 ZNode。就像文件系统中的文件或目录一样,ZNode 是 ZooKeeper 数据模型的基本单元。

ZNode 可以: • 存储数据(每个节点最多约 1MB 数据) • 存储子节点(可以形成路径结构,如 /app/config/key1) • 被客户端监听(watcher)

ZNode 是 ZooKeeper中的最小数据单位,在ZNode下还可以放ZNode。 最终可以形成一个 ZNode Tree 在这里插入图片描述

在 ZooKeeper 中,每一个节点都是 ZNode,上图中有两个节点:

  • app1
  • app2

ZNode节点的路径标识和Unix文件系统路径非常相似,都是用一系列的 "/" 来表示的。 开发人员可以向这个节点写入数据,也可以在这个节点下创建子节点。

ZNode 的结构

每个 ZNode 包含以下信息:

  • 数据内容:用户可存储的数据(字节数组,最大1MB)
  • 版本信息:数据版本(dataVersion)、子节点版本(cversion)等
  • 访问控制列表(ACL):控制权限
  • 时间戳信息:创建时间、修改时间等
  • 统计信息:如子节点数量、创建者 session ID 等

典型用途

  • 配置中心:将配置信息存储为 ZNode,客户端可注册 watcher 实时感知变更
  • 服务注册与发现:服务上线时在某个路径下创建临时 ZNode,掉线后自动清理
  • 分布式锁:使用顺序临时节点创建锁队列,排队加锁
  • 选举机制:使用 EPHEMERAL_SEQUENTIAL 进行主节点选举

Watcher 与 ZNode

ZooKeeper 支持在 ZNode 上注册 watcher:

  • 客户端可以对某个 ZNode 设置 watcher,监听 数据变更 或 子节点变化
  • 但 watch 是一次性的,触发一次后需要重新注册

注意事项

  • ZNode 不是为存储大量数据设计的,推荐将其用于 元数据/状态管理,而非业务数据
  • 临时节点不能有子节点
  • 顺序节点的编号是全局唯一的递增数字
  • watch 的通知机制是 “一次性+轻量级”,不保证强一致

ZNode类型详解

ZooKeeper中的节点类型按照不同的生命周期特性可以分为三大类,每类节点都有特定的使用场景和限制:

  • 持久性节点 (Persistent):基础节点类型,生命周期不受客户端会话影响
  • 临时性节点 (Ephemeral):会话绑定节点,随客户端会话结束而自动删除
  • 顺序性节点 (Sequential):带编号的特殊节点,可应用于分布式协调场景

持久性节点

持久性节点(Persistent)是ZooKeeper中最基础也是最常用的节点类型,具有以下特点:

  1. 持久存在:一旦创建就会一直存在于ZooKeeper服务器上,除非显式删除
  2. 可创建子节点:允许在持久节点下创建其他子节点
  3. 典型应用
    • 配置存储(如数据库连接配置)
    • 服务元数据存储
    • 分布式锁的持久部分

例如,创建一个持久节点:

create /config/database "mysql://user:pass@localhost:3306"

持久顺序节点

持久顺序节点(Persistent Sequential)是持久节点的特殊形式,具有以下特性:

  1. 顺序编号:创建时ZooKeeper会自动在节点名后附加10位数字的递增序号
  2. 持久性:与普通持久节点一样会永久存在
  3. 典型应用
    • 分布式队列
    • 选举序列
    • 有序任务分配

创建示例:

create -s /jobs/job_ "task1"  # 实际创建为/jobs/job_0000000001
create -s /jobs/job_ "task2"  # 实际创建为/jobs/job_0000000002

顺序编号保证了节点在父节点下的创建顺序,这个特性在实现分布式协调时非常有用。

临时节点

临时节点(Ephemeral)是会话绑定的特殊节点类型,特点包括:

  1. 会话绑定:当创建该节点的客户端会话结束时,节点会被自动删除
  2. 不可有子节点:临时节点不能作为父节点创建子节点
  3. 典型应用
    • 服务注册与发现
    • 心跳检测
    • 临时锁

创建示例:

create -e /services/service1 "192.168.1.100:8080"

当客户端断开连接后,该节点会自动消失,非常适合用于服务实例的注册。

临时顺序节点

临时顺序节点(Ephemeral Sequential)结合了临时节点和顺序节点的特性:

  1. 临时性:随会话结束而自动删除
  2. 顺序性:创建时自动附加递增序号
  3. 典型应用
    • 分布式锁实现
    • 领导选举
    • 临时有序任务队列

创建示例:

create -e -s /election/node_ "candidate1"  # 实际创建为/election/node_0000000001
create -e -s /election/node_ "candidate2"  # 实际创建为/election/node_0000000002

这种节点类型在实现公平的分布式锁时特别有用,每个客户端按顺序创建临时顺序节点,序号最小的获得锁。

事务ID

事务是对物理和抽象的应用状态上的操作集合。在现代分布式系统中,事务的概念已经扩展到多个领域,但狭义上的事务通常特指数据库事务。一个数据库事务通常包含一系列有序的读写操作序列,这些操作要么全部执行成功,要么全部失败回滚。

事务的ACID特性

数据库事务必须满足四个核心特性:

  1. 原子性(Atomicity):

    • 事务中的所有操作要么全部完成,要么全部不执行
    • 例如银行转账操作必须同时完成扣款和入账,不能只完成其中一个
  2. 一致性(Consistency):

    • 事务执行前后,数据库都必须处于一致状态
    • 例如转账前后账户总金额必须保持不变
  3. 隔离性(Isolation):

    • 多个并发事务的执行互不干扰
    • 常见隔离级别包括:读未提交、读已提交、可重复读、串行化
  4. 持久性(Durability):

    • 事务一旦提交,其结果将永久保存在数据库中
    • 即使系统崩溃也不会丢失已提交的数据

ZooKeeper中的事务机制

在ZooKeeper分布式协调服务中,事务特指那些能够改变ZooKeeper服务器状态的操作。这些操作包括:

  • 创建节点(create)
  • 删除节点(delete)
  • 设置节点数据(setData)
  • 设置节点ACL(setACL)
  • 创建会话(session)

ZXID事务标识

ZooKeeper为每个事务操作分配一个全局唯一的64位事务ID(ZXID),其结构如下:

| 32位纪元(epoch) | 32位计数器(counter) |

具体特点:

  1. 全局唯一性:在整个ZooKeeper集群中,每个ZXID都是唯一的
  2. 单调递增:ZXID严格递增,可用于判断操作先后顺序
  3. 时间序列:高32位表示leader任期(epoch),低32位是事务计数器
  4. 恢复机制:当leader变更时,epoch会递增,确保新leader的事务ID不会与旧leader冲突

ZXID在ZooKeeper中扮演着重要角色,不仅用于标识事务,还用于:

  • 实现分布式一致性协议(ZAB)
  • 处理客户端请求的顺序保证
  • 故障恢复时的状态同步
  • 快照和日志的版本控制

ZNode测试

客户端连接

我们需要连到:

zkCli.sh

成功连接到ZK: 在这里插入图片描述

SET测试

set / wzk.icu

GET测试

get /

在这里插入图片描述

其他客户端

登录到其他客户端查看数据是否同步: 在这里插入图片描述