点一下关注吧!!!非常感谢!!持续更新!!!
🚀 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案例 详解

章节内容
上一节我们完成了:
- 新建Java的Maven工程
- 使用Java调用ZK 进行操作
- 创建节点、删除节点、监听节点等操作
背景介绍
这里是三台公网云服务器,每台 2C4G,搭建一个Hadoop的学习环境,供我学习。
- 2C4G 编号 h121
- 2C4G 编号 h122
- 2C2G 编号 h123
ZooKeeper简介
核心特性
-
分布式一致性保证:
- 提供顺序一致性(所有更新请求按顺序执行)
- 原子性(更新要么成功要么失败)
- 单一系统镜像(无论连接到哪个服务器,客户端看到的数据视图都是一致的)
- 可靠性(一旦更新被应用,将保持到被下一次更新覆盖)
- 及时性(客户端在一定时间内能看到最新的数据)
-
数据模型:
- 本质上是一个分布式的小文件存储系统,采用类似Unix文件系统的树形层次结构(称为ZNode Tree)
- 每个节点(ZNode)可以存储少量数据(默认上限1MB)
- 节点分为持久节点(PERSISTENT)和临时节点(EPHEMERAL),后者在会话结束后自动删除
-
监控机制(Watcher):
- 客户端可以注册监听特定节点的变化
- 当节点数据变更或子节点列表变化时会触发通知
- 采用一次触发机制,收到通知后需要重新注册
典型应用场景
-
统一命名服务:
- 如Dubbo服务注册中心,服务提供者将服务地址注册到ZooKeeper
- 消费者从ZooKeeper获取可用的服务列表
- 示例:/dubbo/com.example.Service/providers目录下存储服务提供者URL
-
分布式配置管理:
- 如Solr集群配置同步,所有节点监听配置节点
- 配置变更时,管理员更新ZooKeeper上的配置数据
- 各节点收到变更通知后自动获取新配置
- 示例:/solr/configs/mycore目录存储核心配置
-
分布式消息队列:
- 实现发布/订阅模式(Pub/Sub)
- 生产者创建顺序节点作为消息
- 消费者监听父节点获取新消息
- 示例:/queue/msg-0000000001,/queue/msg-0000000002
-
分布式锁:
- 实现互斥锁:多个客户端竞争创建同一个临时节点,成功创建的获得锁
- 实现共享锁:通过节点顺序特性实现读写锁
- 锁释放:会话结束自动删除临时节点或主动删除
-
集群管理:
- 监控集群节点存活状态(通过临时节点)
- 选举主节点(通过节点序号最小的成为Master)
- 示例:/cluster/node1(临时节点)自动消失表示节点下线
Leader选举
选举机制
半数机制:
集群中半数以上机器存活,集群可用。所以 ZooKeeper 适合奇数台。- ZooKeeper 虽然在配置文件中没有指定Master和Slave,但是
ZK在工作的时候
,会有一个Leader
,其他的都是Follower
。
首次启动
假设有五台集群
的机器:
服务1启动
,此时只有它一台启动了,它发出去的报文没有任何响应,所以一直是LOOKING状态
。服务2启动
,它与
最开始启动的服务1进行通信
,互相交换自己的选举结果。由于两者都没有历史数据,所以ID值较大的服务2胜出。但是目前还没有超过半数
的服务同意,所以服务1
和服务2
都是LOOKING状态
。服务3启动
,服务3成了1、2、3的老大,集群中>=2台选了3
,所以服务3成了Leader。服务4启动
,服务4应该是1、2、3的老大,但是集群已
经选了3为老大
,所以4只可以做Follower
。服务5启动
,同4。
非首次启动
每次选举的时候都会根据自身的事务ID
,优先选择事务ID大
的为 Leader。
ZAB 一致性协议详解
ZAB 协议介绍
ZAB(ZooKeeper Atomic Broadcast)是 Apache ZooKeeper 的核心一致性协议,专门为协调服务设计的一种高效原子广播协议。它既是 ZooKeeper 的使用场景,也是其底层实现机制。
ZooKeeper 作为分布式协调服务的工业级解决方案,其核心要解决的就是分布式一致性问题。在理论基础层面,Paxos 算法被认为是解决分布式一致性问题的经典算法,而 ZAB 则是 Paxos 算法在 ZooKeeper 中的具体实现和优化版本。
ZAB 协议的主要特点包括:
- 原子性(Atomic):消息要么被所有节点成功接收,要么全部失败
- 顺序性(Sequential):所有消息严格按照全局顺序进行广播和接收
- 可靠性(Reliable):确保消息最终会被所有节点接收
- 高吞吐(High Throughput):优化了广播过程,提高了系统性能
数据一致性问题详解
分布式数据复制的必要性
在分布式系统中,数据一致性问题产生的根本原因在于数据复制带来的好处与挑战:
-
高可用性:
- 通过将数据复制到多台机器上,可以消除单点故障
- 典型场景:当主服务器宕机时,备份服务器可以立即接管服务
- 示例:金融系统的交易记录通常会在多个数据中心进行备份
-
负载均衡:
- 地理分布的数据副本可以就近服务用户请求
- 提高系统吞吐量和响应速度
- 应用场景:CDN网络中的内容分发就是典型例子
-
容灾备份:
- 多副本可以防止自然灾害导致的数据永久丢失
- 实践案例:跨国企业通常会在不同大洲设立数据中心
数据不一致的产生原因
虽然数据复制带来诸多优势,但也引入了数据一致性问题:
-
网络延迟:
- 副本间同步存在网络传输延迟
- 示例:跨大西洋的数据同步可能需要数百毫秒
-
节点故障:
- 部分节点可能暂时不可用
- 典型情况:服务器维护期间无法接收更新
-
并发写入:
- 多个客户端同时修改不同副本
- 场景示例:电商秒杀活动时的库存更新
-
时序问题:
- 操作顺序在不同节点上可能不一致
- 典型案例:银行转账的先后顺序影响最终余额
这些因素共同导致了分布式系统中的"CAP三角"难题,即在一致性(Consistency)、可用性(Availability)和分区容错性(Partition Tolerance)之间必须做出取舍。ZAB协议正是在这样的背景下被设计出来,在保证分区容错性的前提下,优先确保强一致性。
比如常见于 主从复制的时候
:
主备模式
ZK中,所有客户端
写入数据都是写入Leader
,由Leader复制到Follower
中。
广播消息
ZAB协议的消息广播过程采用了一种优化的二阶段提交机制,包含以下详细步骤:
-
提案阶段(Proposal Phase):
- 当客户端发起写请求时,Leader节点会为这个请求分配一个全局唯一的ZXID(事务ID)
- Leader将请求封装成一个事务Proposal,包含以下内容:
- 事务操作内容
- 事务ID(ZXID)
- 时间戳
- 通过FIFO通道将Proposal发送给所有Follower节点
-
确认阶段(Acknowledge Phase):
- 每个Follower接收到Proposal后:
- 先写入本地事务日志
- 然后向Leader发送ACK响应
- Leader需要等待集群中超过半数节点(包括自己)的ACK响应
- 例如在5节点集群中需要至少3个ACK
- 每个Follower接收到Proposal后:
-
提交阶段(Commit Phase):
- 当获得足够ACK后,Leader会:
- 首先在本地执行Commit操作,将提案应用到状态机
- 然后向所有Follower发送Commit消息
- Follower收到Commit消息后:
- 将提案正式应用到本地状态机
- 向客户端返回响应
- 当获得足够ACK后,Leader会:
这种设计确保了:
- 数据一致性:只有多数节点确认的提案才会被提交
- 高可用性:即使少数节点故障,集群仍可正常工作
- 顺序性:通过ZXID保证所有节点的执行顺序一致
与经典二阶段提交的区别在于:
- 不需要等待所有节点响应,只需多数派
- 引入了事务ID机制保证顺序
- Leader有最终决定权,避免阻塞
发送Proposal到Follower
Leader接收Follower的ACK
超过半数ACK则进行Commit
Leader宕机处理机制
当ZooKeeper集群中的Leader节点发生故障时,整个系统会进入异常状态。ZAB(ZooKeeper Atomic Broadcast)协议专门设计了应对这种情况的机制,确保集群能够快速恢复并保持数据一致性。
Leader宕机的影响
- 服务中断:在Leader选举完成前,集群将暂时无法处理写请求
- 客户端连接:客户端会收到"ConnectionLoss"异常,需要重试或等待
- 事务处理:正在进行的事务可能会被中断
ZAB协议的恢复机制
ZAB协议通过以下方式保证数据一致性:
1. 已提交事务的保证
- 对于已经被Leader提交的事务(即获得集群多数节点ACK确认的事务)
- 新选举出的Leader会确保这些事务最终在所有Follower节点上提交
- 实现方式:通过事务ID(ZXID)比对和事务日志同步
示例流程:
- 新Leader选举成功后,会检查自己的事务日志
- 与其他Follower节点对比ZXID,确定最新已提交的事务
- 通过广播方式让所有节点同步缺失的事务
2. 未完成事务的处理
- 对于只在Leader节点提交/复制但未获得多数确认的事务
- 这些事务会被新Leader主动丢弃
- 实现原理:遵循"超过半数"原则,确保数据一致性
典型场景: 假设集群有5个节点(A为Leader),当A在处理事务T时:
- 若A只将T同步给了B然后就宕机了(仅2/5节点知道T)
- 新Leader选举时会发现T未获得多数确认
- T将被视为无效事务而丢弃
Leader选举过程
ZAB协议采用以下选举算法:
- 选举触发:节点发现与Leader失去连接时会发起选举
- 投票机制:每个节点投票给ZXID最大的节点
- 选举完成:当某个节点获得多数票时成为新Leader
- 数据同步:新Leader会与其他节点同步数据状态
选举通常能在200-400ms内完成,确保快速恢复服务。