【算法】一文彻底搞懂ZAB算法

news2024/10/7 3:29:08

文章目录

  • 什么是ZAB 算法?
  • 深入ZAB算法
    • 1. 消息广播
      • 两阶段提交
      • ZAB消息广播过程
    • 2. 崩溃恢复
      • 选举参数
      • 选举流程
  • ZAB算法需要解决的两大问题
    • 1. 已经被处理的消息不能丢
    • 2. 被丢弃的消息不能再次出现

最近需要设计一个分布式系统,需要一个中间件来存储共享的信息,来保证多个系统之间的数据一致性,调研了两个主流框架Zookeeper和ETCD,发现都能满足我们的系统需求。

其中ETCD是K8s中采用的分布式存储,而其底层采用了RAFT算法来保证一致性,之前已经详细分析了Raft算法的原理,今天主要仔细分析下Zookeeper的底层算法-ZAB算法。

什么是ZAB 算法?

ZAB的全称是 Zookeeper Atomic Broadcast (Zookeeper原子广播)。Zookeeper 是通过 Zab 算法来保证分布式事务的最终一致性。

  • Zab协议是为分布式协调服务Zookeeper专门设计的一种 支持崩溃恢复 的 原子广播协议 ,是Zookeeper保证数据一致性的核心算法。Zab借鉴了Paxos算法,但又不像Paxos那样,是一种通用的分布式一致性算法。它是特别为Zookeeper设计的支持崩溃恢复的原子广播协议。

  • 在Zookeeper中主要依赖Zab协议来实现数据一致性,基于该协议,zk实现了一种主备模型(即Leader和Follower模型)的系统架构来保证集群中各个副本之间数据的一致性。 这里的主备系统架构模型,就是指只有一台客户端(Leader)负责处理外部的写事务请求,然后Leader客户端将数据同步到其他Follower节点。

客户端的读取流程:客户端会随机的链接到 zookeeper 集群中的一个节点,如果是读请求,就直接从当前节点中读取数据;如果是写请求,那么节点就会向 Leader 提交事务,Leader 接收到事务提交,会广播该事务,只要超过半数节点写入成功,该事务就会被提交。

深入ZAB算法

ZAB算法分为两大块内容,消息广播和崩溃恢复。

  • 消息广播(boardcast):Zab 协议中,所有的写请求都由 leader 来处理。正常工作状态下,leader 接收请求并通过广播协议来处理。

  • 崩溃恢复(recovery):当服务初次启动,或者 leader 节点挂了,系统就会进入恢复模式,直到选出了有合法数量 follower 的新 leader,然后新 leader 负责将整个系统同步到最新状态。

1. 消息广播

消息广播的过程实际上是一个简化的两阶段提交过程,这里对两阶段提交做一个简单的介绍。

两阶段提交

两阶段提交算法本身是一致强一致性算法,适合用作数据库的分布式事务,其实数据库的经常用到的TCC本身就是一种2PC。

下面以MySQL中对数据库的修改过程,来介绍下两阶段提交的具体流程,在MySQL中对一条数据的修改操作首先写undo日志,记录的数据原来的样子,接下来执行事务修改操作,把数据写到redo日志里面,万一捅娄子,事务失败了,可从undo里面恢复数据。数据库通过undo与redo能保证数据的强一致性。

  • 首先第一阶段叫准备节点,事务的请求都发送给一个个的资源,这里的资源可以是数据库,也可以是其他支持事务的框架,他们会分别执行自己的事务,写日志到undo与redo,但是不提交事务。

  • 当事务管理器收到了所以资源的反馈,事务都执行没报错后,事务管理器再发送commit指令让资源把事务提交,一旦发现任何一个资源在准备阶段没有执行成功,事务管理器会发送rollback,让所有的资源都回滚。这就是2pc,非常简单。
    在这里插入图片描述

说他是强一致性的是他需要保证任何一个资源都成功,整个分布式事务才成功。

优点:原理简单,实现方便
缺点:同步阻塞,单点问题,数据不一致,容错性不好

  • 同步阻塞:在二阶段提交的过程中,所有的节点都在等待其他节点的响应,无法进行其他操作。这种同步阻塞极大的限制了分布式系统的性能。
  • 单点问题:协调者在整个二阶段提交过程中很重要,如果协调者在提交阶段出现问题,那么整个流程将无法运转。更重要的是,其他参与者将会处于一直锁定事务资源的状态中,而无法继续完成事务操作。
  • 数据不一致:假设当协调者向所有的参与者发送commit请求之后,发生了局部网络异常,或者是协调者在尚未发送完所有 commit请求之前自身发生了崩溃,导致最终只有部分参与者收到了commit请求。这将导致严重的数据不一致问题。
  • 容错性不好:二阶段提交协议没有设计较为完善的容错机制,任意一个节点是失败都会导致整个事务的失败。

ZAB消息广播过程

Zookeeper集群中,存在以下三种角色的节点:

Leader:Zookeeper集群的核心角色,在集群启动或崩溃恢复中通过Follower参与选举产生,为客户端提供读写服务,并对事务请求进行处理。

Follower:Zookeeper集群的核心角色,在集群启动或崩溃恢复中参加选举,没有被选上就是这个角色,为客户端提供读取服务,也就是处理非事务请求,Follower不能处理事务请求,对于收到的事务请求会转发给Leader。

Observer:观察者角色,不参加选举,为客户端提供读取服务,处理非事务请求,对于收到的事务请求会转发给Leader。使用Observer的目的是为了扩展系统,提高读取性能。

  • Leader 接收到消息请求后,将消息赋予一个全局唯一的 64 位自增 id,叫做:zxid,通过 zxid 的大小比较即可实现因果有序这一特性。

  • Leader 通过先进先出队列(通过 TCP 协议来实现,以此实现了全局有序这一特性)将带有 zxid 的消息作为一个提案(proposal)分发给所有 follower。

  • 当 follower 接收到 proposal,先将 proposal 写到硬盘,写硬盘成功后再向 leader 回一个 ACK。

  • 当 leader 接收到合法数量的 ACKs 后,leader 就向所有 follower 发送 COMMIT 命令,同时会在本地执行该消息。
    当 follower 收到消息的 COMMIT 命令时,就会执行该消息。
    在这里插入图片描述

相比于完整的二阶段提交,Zab 协议最大的区别就是不能终止事务,follower 要么回 ACK 给 leader,要么抛弃 leader,在某一时刻,leader 的状态与 follower 的状态很可能不一致,因此它不能处理 leader 挂掉的情况,所以 Zab 协议引入了恢复模式来处理这一问题。
从另一角度看,正因为 Zab 的广播过程不需要终止事务,也就是说不需要所有 follower 都返回 ACK 才能进行 COMMIT,而是只需要合法数量(2n+1 台服务器中的 n+1 台) 的follower,也提升了整体的性能。

Leader 服务器与每一个 Follower 服务器之间都维护了一个单独的 FIFO 消息队列进行收发消息,使用队列消息可以做到异步解耦。
Leader 和 Follower 之间只需要往队列中发消息即可。如果使用同步的方式会引起阻塞,性能要下降很多。

2. 崩溃恢复

崩溃恢复的主要任务就是选举Leader(Leader Election),Leader选举分两个场景:

  • Zookeeper服务器启动时Leader选举。
  • Zookeeper集群运行过程中Leader崩溃后的Leader选举。

选举参数

在介绍选举流程之前,需要介绍几个参数,

  • myid: 服务器ID,这个是在安装Zookeeper时配置的,myid越大,该服务器在选举中被选为Leader的优先级会越大。ZAB算法中通过myid来规避了多个节点可能有相同zxid问题,注意可以对比之前的Raft算法,Raft算法中通过随机的timeout来规避多个节点可能同时成为Leader的问题。
  • zxid: 事务ID,这个是由Zookeeper集群中的Leader节点进行Proposal时生成的全局唯一的事务ID,由于只有Leader才能进行Proposal,所以这个zxid很容易做到全局唯一且自增。因为Follower没有生成zxid的权限。zxid越大,表示当前节点上提交成功了最新的事务,这也是为什么在崩溃恢复的时候,需要优先考虑zxid的原因。
  • epoch: 投票轮次,每完成一次Leader选举的投票,当前Leader节点的epoch会增加一次。在没有Leader时,本轮此的epoch会保持不变。

另外在选举的过程中,每个节点的当前状态会在以下几种状态之中进行转变。

  • LOOKING: 竞选状态。
  • FOLLOWING: 随从状态,同步Leader 状态,参与Leader选举的投票过程。
  • OBSERVING: 观察状态,同步Leader 状态,不参与Leader选举的投票过程。
  • LEADING: 领导者状态。

选举流程

选举的流程如下:

  • 每个Server会发出一个投票,第一次都是投自己。投票信息:(myid,ZXID)
  • 收集来自各个服务器的投票
  • 处理投票并重新投票,处理逻辑:优先比较ZXID,然后比较myid
  • 统计投票,只要超过半数的机器接收到同样的投票信息,就可以确定leader
  • 改变服务器状态,进入正常的消息广播流程。
    在这里插入图片描述

ZAB算法需要解决的两大问题

1. 已经被处理的消息不能丢

这一情况会出现在以下场景:当 leader 收到合法数量 follower 的 ACKs 后,就向各个 follower 广播 COMMIT
命令,同时也会在本地执行 COMMIT 并向连接的客户端返回「成功」。但是如果在各个 follower 在收到 COMMIT 命令前
leader 就挂了,导致剩下的服务器并没有执行都这条消息。

为了实现已经被处理的消息不能丢这个目的,Zab 的恢复模式使用了以下的策略:

  • 选举拥有 proposal 最大值(即 zxid 最大) 的节点作为新的 leader:由于所有提案被 COMMIT 之前必须有合法数量的 follower ACK,即必须有合法数量的服务器的事务日志上有该提案的 proposal,因此,只要有合法数量的节点正常工作,就必然有一个节点保存了所有被 COMMIT 的 proposal。 而在选举Leader的过程中,会比较zxid,因此选举出来的Leader必然会包含所有被COMMIT的proposal。
  • 新的 leader 将自己事务日志中 proposal 但未 COMMIT 的消息处理。
    新的 leader 与 follower 建立先进先出的队列, 先将自身有而 follower 没有的 proposal 发送给 follower,再将这些 proposal 的 COMMIT 命令发送给 follower,以保证所有的 follower 都保存了所有的 proposal、所有的 follower 都处理了所有的消息。

2. 被丢弃的消息不能再次出现

这一情况会出现在以下场景:当 leader 接收到消息请求生成 proposal 后就挂了,其他 follower 并没有收到此
proposal,因此经过恢复模式重新选了 leader 后,这条消息是被跳过的。 此时,之前挂了的 leader 重新启动并注册成了
follower,他保留了被跳过消息的 proposal 状态,与整个系统的状态是不一致的,需要将其删除。

在这里插入图片描述

Zab 通过巧妙的设计 zxid 来实现这一目的。一个 zxid 是64位,高 32 是纪元(epoch)编号,每经过一次 leader 选举产生一个新的 leader,新 leader 会将 epoch 号 +1。低 32 位是消息计数器,每接收到一条消息这个值 +1,新 leader 选举后这个值重置为 0。这样设计的好处是旧的 leader 挂了后重启,它不会被选举为 leader,因为此时它的 zxid 肯定小于当前的新 leader。当旧的 leader 作为 follower 接入新的 leader 后,新的 leader 会让它将所有的拥有旧的 epoch 号的未被 COMMIT 的 proposal 清除。

Zab 协议设计的优秀之处有两点,一是简化二阶段提交,提升了在正常工作情况下的性能;二是巧妙地利用率自增序列,简化了异常恢复的逻辑,也很好地保证了顺序处理这一特性。

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

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

相关文章

手把手教你开发第一个HarmonyOS (鸿蒙)移动应用

⼀、移动应⽤开发的介绍 移动应⽤开发: AndroidIOSHarmonyOS (鸿蒙) ⼆、HarmonyOS介绍 文档概览-HarmonyOS应用开发官网 2.1 系统的定义 2.1.1 系统的定位 HarmonyOS有三⼤特征: 搭载该操作系统的设备在系统层⾯融为⼀体、形成超级终…

常见元件、封装、尺寸、表面处理等

参考:https://www.bilibili.com/read/cv11024927?fromsearch&spm_id_from333.337.0.0 参考:https://www.bilibili.com/read/cv18413169?fromsearch&spm_id_from333.337.0.0 目录 通孔插件(THT)和表面贴装(SMT)技术封装类型SOP/SOIC封装DIP封装…

实战打靶集锦-018-decoy

提示:本文记录了博主的一次打靶过程 目录 1. 主机发现2. 端口扫描3. 服务枚举4. 服务探查4.1 浏览器探查 5. 突破边界6. 提权6.1 rbash绕过6.2 枚举系统信息6.3 枚举定时任务6.4 枚举可执行文件 7. 获取flag 1. 主机发现 目前只知道目标靶机在65.xx网段&#xff0c…

thinkphp6数据库操作

文章目录 数据库链接 查询构造器查询 添加修改删除链式操作链式操作wheretablefieldpageodrderjoincache 聚合查询分页查询 数据库 链接 在config下有个database.php文件,一般情况下我们配置这个文件即可 return [default > mysql,connections > …

学习记录:2023.4.27

2023.4.27 实习学习记录 Vue连接远程数据库Java基础 Vue cursor: pointer; 表示鼠标指针在该元素上时会变成手形,表示该元素可以被点击或者有交互性。这是一种CSS样式属性,常用于网页设计中。VueECharts实现热词图: 1、安装依赖:…

Linux命令集(Linux常用命令--cat指令篇)

Linux命令集(Linux常用命令--cat指令篇) Linux常用命令集(cat指令篇)4.cat(concatenate)1. 查看文件内容:2. 连接多个文件:3. 创建文件并通过终端写入内容4. 输出内容编号 Linux常用命令集(cat指…

操作系统概述

概述 一、简单描述 1、系统资源的管理者; 2、最接近硬件的一层软件; 3、向上层提供方便容易使用的服务; 二、提供的功能 1、处理机管理; 2、储存器管理; 3、文件管理; 4、设备管理; 举例说明…

Redis学习——day01

Redis学习基础 Nosql:Redis入门:Redis安装:Windows:Linux安装: Nosql: Nosql Not Only Sql(不仅仅Sql)NoSQL,泛指非关系型的数据库。随着互联网web2.0网站的兴起&#…

了解 AlphaFold2 论文必备知识,不会有人还不知道吧

你知道 AlphaFold2 吗?它真正解决了蛋白质三维结构预测的算法困境,堪称蛋白质界的 chat-GPT4,甚至它的意义不是 chat-GPT4 所能够匹敌的。它为世界疾病治疗药物开发以及探究生物生命之谜提供了通向天神的一条道路,未来是生物的世纪…

深入与浅谈 Vue 中计算属性和侦听器的区别和使用(Vue3版本为例)

#五一技术创作马拉松# 📋前言 计算属性 computed 和侦听器 watch 都是 Vue.js 框架中用来响应式更新视图的重要概念。在 Vue 项目开发中,这两个技术点是非常重要的,同时也是 Vue 基础中不可缺少的知识点。在面试中,计算属性 comp…

【前端知识】内存泄漏与垃圾回收机制 (下)

【前端知识相关分享】内存泄漏与垃圾回收机制 (下) 6. 内存泄漏的解决方法6.1 解决方法概述6.2 什么是垃圾6.3 垃圾回收机制的定义及规则6.4 垃圾回收算法的基本流程 7. 垃圾回收的常见算法7.1 引用计数7.2 标记清除7.3 复制算法7.4 标记整理&#xff08…

十大经典排序算法总结(C语言版本)

前言:排序算法是最经典的算法知识,也是每个合格程序员应该需要掌握的知识点。考虑到排序算法通常代码简短,逻辑思维强和应用范围广等特性,排序算法题目便成为了面试中的常客。在面试中最常考的是快速排序和归并排序等基本的排序算…

SQL(基础)

DDL: 数据定义语言 Definition,用来定义数据库对象(数据库、表、字段)CREATE、DROP、ALTER DML: 数据操作语言 Manipulation,用来对数据库表中的数据进行增删改 INSERT、UPDATE、DELETE 注意: DDL是改变表的结构 DML…

一以贯之:从城市网络到“城市一张网”

《论语里仁》中子曰:“参乎,吾道一以贯之”。 孔子所说的“一以贯之”,逐渐成为了中国文化与哲学的重要组成部分,指明事物发展往往需要以标准化、集约化、融合化作为目标。这种智慧在数字化发展中格外重要。从云计算、大数据技术模…

一个快速去除黑背景和其他颜色背景,生成透明PNG图的小工具

做粒子效果或者其他一些图案的时候,时常能找到不少原图,但是却有黑色的背景或者其他背景色,导致用起来比较麻烦。这个小工具就可以方便的去除黑背景,生成透明PNG图,可以把想要的图案方便的取出来。 链接请见&#xff…

【Arduino 和 DS3231 实时时钟教程】

【Arduino 和 DS3231 实时时钟教程】 1. 概述2. 原理分析3. DS3231 实时时钟4. 编程1. 概述 在本Arduino教程中,我们将学习如何使用DS3231实时时钟模块。您可以观看以下视频或阅读下面的书面教程。 2. 原理分析 这里出现的第一个问题是,当Arduino本身具有内置计时器时,为什…

利用倾斜摄影超大场景的三维模型轻量化技术如何提高网络传输的效率?

利用倾斜摄影超大场景的三维模型轻量化技术如何提高网络传输的效率? 倾斜摄影超大场景的三维模型轻量化在网络传输中的效率可以通过以下几个方面进行提高: 一、数据压缩 对于倾斜摄影超大场景的三维模型数据,可以采用数据轻量化压缩技术进…

如何利用ChatPDF快速阅读英文论文,帮你写文章

如何利用ChatPDF快速阅读英文论文,帮你写文章 英语渣狂喜~确实惊艳到我了! 使用平台:https://www.chatpdf.com/ 1、上传PDF 访问官网:https://www.chatpdf.com/,界面很美,点击直接上传 PDF&…

Python小姿势 - Python学习笔记——类与对象

Python学习笔记——类与对象 类与对象是面向对象编程的两个基本概念。类是对象的抽象概念,对象是类的具体表现。 类是对一类事物的抽象,它是描述一类事物的模板,而对象是类的具体表现。对象是类的实例,类是对象的模板。 举个例子&…

【Midjourney】Midjourney 连续性人物创作 ④ ( 使用 URL + Seed 随机种子生成连续性的人物 )

文章目录 一、生成图片并获取 Seed二、使用 URL Seed 随机种子生成连续性的人物 使用 URL 链接 和 Seed 随机种子 生成连续性人物 , 必须先生成一组图片 , 然后按 U 按钮 , 选择一张大图 , 之后所有的连续性人物图片都基于该图片进行生成 ; 使用 URL Seed 随机种子生成连续性…