深入理解 ZAB:ZooKeeper 原子广播协议的工作原理

news2025/5/20 14:22:23

在这里插入图片描述

目录

      • ZAB 协议:ZooKeeper 如何做到高可用和强一致?🔒
      • ZAB 协议的核心目标 🎯
      • ZAB 协议的关键概念 💡
      • ZAB 协议的运行阶段 🎬
        • 阶段一:Leader 选举 (Leader Election) 🗳️
        • 阶段二:发现与同步 (Discovery and Synchronization) 📡🤝
        • 阶段三:广播 (Broadcast) 📢✅
      • ZAB 协议如何保证一致性?🔒
      • 总结:可靠的分布式协调基石 💎

🌟我的其他文章也讲解的比较有趣😁,如果喜欢博主的讲解方式,可以多多支持一下,感谢🤗!

其他优质专栏: 【🎇SpringBoot】【🎉多线程】【🎨Redis】【✨设计模式专栏(已完结)】…等

如果喜欢作者的讲解方式,可以点赞收藏加关注,你的支持就是我的动力
✨更多文章请看个人主页: 码熔burning

ZAB 协议:ZooKeeper 如何做到高可用和强一致?🔒

在使用 Apache ZooKeeper 时,我们知道它是一个分布式协调服务,常用于配置管理、命名服务、分布式同步(如分布式锁)、组服务等。ZooKeeper 能够提供高可用和一致性的服务,其核心秘诀就在于它内部实现的ZAB (ZooKeeper Atomic Broadcast) 协议。

ZAB 协议是专为 ZooKeeper 设计的一种崩溃可恢复的原子广播协议。它的主要目标是确保 ZooKeeper 服务的所有副本(称为 Peer,包括 Leader 和 Follower)之间保持状态的一致性,并且所有对状态的更新(事务)都能够按照全局唯一的顺序被处理。

简单来说,ZAB 协议就是要解决如何在分布式环境中,让大家(ZooKeeper 的各个节点)对同一个事情(数据更新)达成一致意见,并且这个过程是可靠的,即使有节点崩溃了也能恢复。🤝

ZAB 协议的核心目标 🎯

ZAB 协议主要确保以下两点:

  1. 一致性 (Consistency): 保证所有正确的 ZooKeeper 节点都具有相同的系统状态副本。无论客户端连接到哪个节点,都能看到相同的数据。
  2. 全局有序性 (Global Ordering): 所有修改 ZooKeeper 状态的事务都会被赋予一个全局唯一的序列号,并且所有节点都会按照这个序列号的顺序来处理这些事务。

ZAB 协议的关键概念 💡

理解 ZAB 协议,需要先掌握几个核心概念:

  • 原子广播 (Atomic Broadcast): ZAB 协议的核心思想。它保证了任何一个事务(对 ZooKeeper 状态的修改操作)要么被 ZooKeeper 集群中的所有节点都接受并处理,要么一个节点都不处理。并且,所有节点处理这些事务的顺序是完全一致的。想象一下电视直播,所有观众看到的画面内容和顺序都是一样的。📺
  • 角色 (Roles): 在 ZooKeeper 集群中,节点主要有三种角色:
    • Leader (领导者): 集群中只有一个 Leader,负责处理所有的写请求(状态修改)。它接收客户端的写请求,生成新的事务,并将事务广播给 Follower。📢
    • Follower (跟随者): 负责同步 Leader 发来的事务,并将事务应用到自己的状态上。它处理客户端的读请求。👥
    • Observer (观察者): 与 Follower 类似,也同步 Leader 发来的事务并应用到自己的状态上。但它不参与 Leader 选举和写请求的投票过程。主要用于扩展读性能。👀
  • 事务 (Transaction): 对 ZooKeeper 状态的每一次修改操作都抽象为一个事务。例如,创建节点、删除节点、设置节点数据等都是事务。📝
  • Zookeeper 事务 ID (ZXID): 每个事务都有一个唯一的 64 位数字标识,称为 ZXID。ZXID 是单调递增的,它保证了事务的全局顺序性。ZXID 的高 32 位通常代表 Leader 的周期(Epoch),低 32 位代表该 Epoch 内的事务序列号。🔢
  • 周期 (Epoch): Leader 选举成功后,新的 Leader 会创建一个新的 Epoch。Epoch 是一个单调递增的数字,用来标识 Leader 的一个任期。每次发生 Leader 切换,Epoch 都会增加。Epoch 的作用是为了区分不同 Leader 任期内产生的事务。🗓️
  • 过半机制 (Quorum): ZAB 协议基于过半机制来实现一致性和可靠性。任何一个写事务,都需要集群中半数以上的节点(包括 Leader 自己)成功接收并确认,Leader 才会提交这个事务。同样,Leader 的选举也需要获得过半节点的投票。🗳️

ZAB 协议的运行阶段 🎬

ZAB 协议的运行主要分为三个阶段:

阶段一:Leader 选举 (Leader Election) 🗳️

当 ZooKeeper 集群启动时,或者当前的 Leader 发生故障、网络中断时,集群会进入 Leader 选举阶段。

这个阶段的目标是从所有正常运行的节点中选举出一个新的 Leader。选举过程可能会比较复杂,但核心是基于某种规则(比如每个节点都会给自己投票,并向其他节点发送自己的投票信息,包括自己认为的 Leader 及其最新的事务 ID ZXID)进行协商,最终得票过半的节点成为新的 Leader。

新的 Leader 诞生后,会生成一个新的 Epoch,这个 Epoch 将作为后续事务 ZXID 的高 32 位。

阶段二:发现与同步 (Discovery and Synchronization) 📡🤝

新的 Leader 选举出来后,它并不知道其他 Follower 节点当前的状态是什么样的。有些 Follower 可能丢失了一些最新的事务,有些可能还停留在旧的 Leader 周期。

这个阶段的目标是让新的 Leader 和所有 Follower 达到一致的状态,特别是保证所有 Follower 都拥有 Leader 提议过的所有事务。

具体过程大致是:

  1. 新的 Leader 会与所有 Follower 建立连接。

  2. Follower 会向 Leader 报告自己当前接收到的最新事务的 ZXID

  3. Leader 会根据 Follower 报告的 ZXID,找出 Follower 缺失的事务。

    • 如果 Follower 的 ZXID 落后于 Leader,Leader 会将 Follower 缺失的事务发送给它进行同步。
    • 如果 Follower 的 ZXID 甚至超前于 Leader (这在理论上不应该发生,但在某些极端情况下可能存在脏数据),Leader 会要求 Follower 回滚到 Leader 的最新状态。
  4. Leader 需要等待过半的 Follower 完成同步,确保大多数节点的状态与 Leader 一致。

这个阶段非常重要,它保证了在开始处理新的写请求之前,集群中的大多数节点已经处于一个一致的、最新的状态。

阶段三:广播 (Broadcast) 📢✅

一旦过半的 Follower 与 Leader 完成同步,集群就进入了正常运行的广播阶段。

在这个阶段,Leader 开始接收客户端的写请求。对于每一个写请求,Leader 会执行以下操作:

  1. 生成新的事务: 将客户端的写请求转换为一个内部的事务对象,并分配一个新的、单调递增的 ZXID(新的 Epoch + 当前 Epoch 内的计数器)。
  2. 提议 (Propose): Leader 将这个新的事务提议给所有的 Follower。
  3. 广播 (Broadcast): Leader 将事务发送给所有连接的 Follower。
  4. 确认 (Acknowledge): Follower 收到事务提议后,会将其写入自己的事务日志,并向 Leader 发送一个确认 (ACK)。📝➡️👍
  5. 提交 (Commit): Leader 收到过半的 Follower 的确认后,认为这个事务已经被大多数节点接受, Leader 就会向所有 Follower 发送一个 Commit 命令。收到 Commit 命令的 Follower 会将事务应用到自己的内存状态中。Leader 自己也会将事务应用到自己的状态中。✨

整个广播过程是原子性的: 事务要么在所有节点上都提交,要么都不提交。并且,由于 ZXID 的全局有序性,所有节点都会按照 ZXID 的顺序来处理和应用事务,保证了状态的一致。

ZAB 协议如何保证一致性?🔒

ZAB 协议通过结合上述概念和阶段,保证了分布式环境下的数据一致性:

  • Leader 选举和 Epoch: 每次 Leader 切换都引入新的 Epoch,保证了不同 Leader 周期产生的事务不会混淆。新的 Leader 会基于大多数节点的状态来确定从哪里开始新的 Epoch 和 ZXID,避免了脑裂问题导致的不同 Leader 提交冲突的事务。
  • ZXID 的单调递增: 为每个事务提供了唯一的全局顺序标识,所有节点按序处理,保证了事务应用的顺序一致。
  • 过半机制: 任何写操作的提交都依赖于过半节点的确认。这意味着如果一个事务被提交了,它就肯定存在于集群中至少过半的节点上。当发生故障需要选举新的 Leader 时,新的 Leader 一定是从拥有最新已提交事务(最高 ZXID)的节点中选出的,从而保证了新的 Leader 的状态包含了所有已提交的事务。即使旧的 Leader 提议了某个事务但未获得过半确认就崩溃了,新的 Leader 也不会提交那个未完成的事务。半数以下的节点崩溃不会影响服务的可用性。💪

总结:可靠的分布式协调基石 💎

ZAB 协议是 ZooKeeper 能够提供可靠的分布式协调服务的基石。它通过 Leader 选举、基于 Epoch 和 ZXID 的事务排序、以及原子广播和过半机制,巧妙地解决了分布式环境下的数据一致性和可靠性问题。

理解 ZAB 协议对于深入学习 ZooKeeper、设计和实现高可用的分布式系统都非常有帮助!虽然它的细节实现比较复杂,但掌握其核心思想和工作流程,能让你更好地理解 ZooKeeper 的行为和性能。😊

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2380022.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

GraphPad Prism项目的管理

《2025新书现货 GraphPad Prism图表可视化与统计数据分析(视频教学版)雍杨 康巧昆 清华大学出版社教材书籍 9787302686460 GraphPadPrism图表可视化 无规格》【摘要 书评 试读】- 京东图书 GraphPad Prism统计数据分析_夏天又到了的博客-CSDN博客 项目…

驱动-Linux定时-timer_list

了解内核定时相关基础知识 文章目录 简要介绍timer_list 特点API 函数实验测试程序 - timer_mod.c编译文件-Makefile实验验证 注意事项总结 简要介绍 硬件为内核提供了一个系统定时器来计算流逝的时间(即基于未来时间点的计时方式, 以当前时刻为计时开始…

STM32F103_LL库+寄存器学习笔记22 - 基础定时器TIM实现1ms周期回调

导言 如上所示,STM32F103有两个基本定时器TIM6与TIM7,所谓「基本定时器」,即功能最简单的定时器。 项目地址: github: LL库: https://github.com/q164129345/MCU_Develop/tree/main/stm32f103_ll_library22_Basic_Timer寄存器方…

5个yyds的.Net商城开源项目

今天一起来盘点下5个商城开源项目。 1、支持多语言、多商店的商城,.Net7 EF7领域驱动设计架构(Smartstore) 项目简介 Smartstore 支持桌面和移动平台、多语言、多商店、多货币的商城,并支持SEO优化,支持无限数量的…

[项目深挖]仿muduo库的并发服务器的解析与优化方案

标题:[项目深挖]仿muduo库的并发服务器的优化方案 水墨不写bug 文章目录 一、buffer 模块(1)线性缓冲区直接扩容---->环形缓冲区定时扩容(只会扩容一次)(2)使用双缓冲(Double Buf…

国标GB28181视频平台EasyGBS校园监控方案:多场景应用筑牢安全防线,提升管理效能

一、方案背景​ 随着校园规模不断扩大,传统监控系统因设备协议不兼容、数据分散管理,导致各系统之间相互独立、数据无法互通共享。在校园安全防范、教学管理以及应急响应过程中,这种割裂状态严重影响工作效率。国标GB28181软件EasyGBS视频云…

SHIMADZU岛津 R300RC300 Operation Manual

SHIMADZU岛津 R300RC300 Operation Manual

使用 Docker 部署 React + Nginx 应用教程

目录 1. 创建react项目结构2. 创建 .dockerignore3. 创建 Dockerfile4. 创建 nginx.conf5. 构建和运行6. 常用命令 1. 创建react项目结构 2. 创建 .dockerignore # 依赖目录 node_modules npm-debug.log# 构建输出 dist build# 开发环境文件 .git .gitignore .env .env.local …

API Gateway REST API 集成 S3 服务自定义 404 页面

需求分析 使用 API Gateway REST API 可以直接使用 S3 作为后端集成对外提供可以访问的 API. 而当访问的 URL 中存在无效的桶, 或者不存在的对象时, API Gateway 默认回向客户端返回 200 状态码. 而实际上这并不是正确的响应, 本文将介绍如何自定义返回 404 错误页面. 基本功…

关于systemverilog中在task中使用force语句的注意事项

先看下面的代码 module top(data);logic clk; inout data; logic temp; logic sampale_data; logic [7:0] data_rec;task send_data(input [7:0] da);begin(posedge clk);#1;force datada[7];$display(data);(posedge clk);#1;force datada[6]; $display(data); (posed…

Python Day26 学习

继续NumPy的学习 数组的索引 一维数组的索引 创建及输出 arr1d np.arange(10) # 数组: [0 1 2 3 4 5 6 7 8 9] arr1d array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) 取出数组的第一个元素,最后一个元素 代码实现 arr1d[0] arr1d[-1] 取出数组中索引为3&#x…

解决:npm install报错,reason: certificate has expired

目录 1. 问题分析2. 问题解决2.1 查看配置的镜像2.2 修改镜像源 种一棵树最好的时间是10年前,其次就是现在,加油! --by蜡笔小柯南 1. 问题分析 启动前…

中科固源Wisdom平台发现NASA核心飞行控制系统(cFS)通信协议健壮性缺陷!

中科固源Wisdom平台发现NASA核心飞行控制系统(cFS)通信协议健壮性缺陷,接下来内容将进行核心要点概述,分别从地位、重要性和应用场景三方面进行简明阐述: cFS(core Flight System)是NASA戈达德太空飞行中心&#xff08…

嵌入式学习笔记DAY23(树,哈希表)

一、树 1.树的概念 之前我们一直在谈的是一对一的线性结构,现实中,还存在很多一对多的情况需要处理,一对多的线性结构——树。 树的结点包括一个数据元素及若干指向其子树的分支,结点拥有的子树数称为结点的度。度为0的结点称为叶…

仓颉开发语言入门教程:搭建开发环境

仓颉开发语言作为华为为鸿蒙系统自研的开发语言,虽然才发布不久,但是它承担着极其重要的历史使命。作为鸿蒙开发者,掌握仓颉开发语言将成为不可或缺的技能,今天我们从零开始,为大家分享仓颉语言的开发教程,…

Axure中继器高保真交互原型的核心元件

Axure作为一款强大的原型设计工具,中继器无疑是打造高保真交互原型的核心利器。今天,就让我们深入探讨一下Axure中继器的核心地位、操作难点,以及如何借助优秀案例来提升我们的中继器使用技能。 一、核心地位 中继器在Axure中的地位举足轻重…

【SpringBoot】✈️整合飞书群机器人发送消息

💥💥✈️✈️欢迎阅读本文章❤️❤️💥💥 🏆本篇文章阅读大约耗时3分钟。 ⛳️motto:不积跬步、无以千里 📋📋📋本文目录如下:🎁🎁&am…

第 1 章:数字 I/O 与串口通信(GPIO UART)

本章目标: 掌握 GPIO 的硬件原理、寄存器配置与典型驱动框架 深入理解 UART/USART 的帧格式、波特率配置、中断与 DMA 驱动 通过实战案例,将 GPIO 与 UART 结合,实现 AT 命令式外设控制 章节结构 GPIO 概述与硬件原理 GPIO 驱动实现:寄存器、中断与去抖 UART/USART 原理与帧…

【图像生成大模型】Wan2.1:下一代开源大规模视频生成模型

Wan2.1:下一代开源大规模视频生成模型 引言Wan2.1 项目概述核心技术1. 3D 变分自编码器(Wan-VAE)2. 视频扩散 Transformer(Video Diffusion DiT)3. 数据处理与清洗 项目运行方式与执行步骤1. 环境准备2. 安装依赖3. 模…

interface接口和defer场景分析

接口 接口这里主要两点: 设计业务结构时采用依赖倒转:业务层向下依赖抽象层,实现层向上依赖抽象层。 相比于之前: 之后: 注意struct中嵌套interface和不嵌套interface的区别: type Myinterface interfac…