分布式与一致性协议之ZAB协议(五)
ZAB协议
ZAB集群如何从故障中恢复
如果我们想把ZAB集群恢复到正常状态,那么新领导者就必须确立自己的领导关系,成为唯一有效的领导者,然后作为主节点"领导"各备份节点一起处理读写请求
如何确立领导关系
前面提到,选举出的领导者是在成员发现阶段确立领导关系的。领导者在当选后会递增自己的任期编号,并基于任期编号值的大小来与跟随者协商,最终建立领导关系。具体来说,跟随者会选择任期编号值最大的节点来作为自己的领导者,而被大多数节点认同的领导者将成为真正的领导者。
举个例子。
下面用一个例子来帮助更好地理解。
假设一个ZooKeeper集群由节点A、B、C组成。其中,领导者A已经宕机,节点C是新选出来的领导者,节点B是新的跟随者(为了方便演示,假设节点B、C已提交提案的事务标识符的最大值分别是<1,10>和<1,11>,其中1是任期编号,10、11是事务标识符中的计数器值,节点A宕机前的任期编号也是1),如图所示。那么节点B、C如何协商建立领导关系呢?
- 首先,节点B、C会把自己的ZAB状态设置为成员发现(DISCOVERY),这就表明,选举(ELECTION)阶段结束了,进入了下一个阶段,如图所示。
这里补充一下,ZAB协议定义了4种状态来标识节点的运行状态。
1.ELECTION(选举)状态:表明节点在进行领导者选举
2.DISCOVERY(成员发现)状态:表明节点在协商沟通领导者的合法性
3.SYNCHRONIZATION(数据同步)状态:表明集群的各节点以领导者的数据为准,修复数据副本的一致性
4.BROADCAST(广播)状态:表明集群各节点在正常处理写请求。
关于这4种状态,简单了解即可。强调一点,只有当集群大多数节点处于广播状态的时候,集群才能提交提案。
- 接下来,节点B会主动向节点C发送包含自己接收到的领导者任期编号的最大值(也就是前领导者A的任期编号,1)的FOLLOWINFO消息,如图所示。
节点C在接收到来自节点B的信息后,会将包含自己的事务标识符的最大值的LEADINFO消息发送给跟随者。需要注意的是,领导者进入成员发现阶段后会对任期编号加1,即创建新的任期编号,然后基于新任期编号创建新的事务标识符(也就是<2,0>),如图所示。
当接收到领导者的响应后,跟随者会判断领导者的任期编号是否最新,如果不是,就发起新的选举;如果是,则返回ACKEPOCH消息给领导者。在这里,
节点C的任期编号(也就是2)大于节点B接收到的其他领导任期编号(也就是旧领导者A的任期编号,1),所以节点B返回确认响应给节点C,并设置ZAB状态为数据同步状态,如图所示
- 最后,领导者在接收到来自大多数节点的ACKEPOCH消息时,会设置ZAB状态为数据同步。在这里,节点C接收到了节点B和节点C自己发送的消息,满足大多数节点的要求,所以,在接收到来自B的消息后,C设置ZAB状态为数据同步状态。如图所示
现在,ZAB协议在成员发现阶段确立了领导者的领导关系,这样领导者就可以行使领导职能了。下一步,ZAB协议要解决的就是数据冲突问题,以实现各节点数据的一致性,那么它是怎么做的呢?
如何处理冲突数据
当进入数据同步状态后,领导者会根据跟随者的事务标识符的最大值,判断以哪种方式处理不一致数据(有DIFF、TRUNC、SNAP3种方式)。
因为节点C已提交提案的事务标识符的最大值(也就是<1,11>)大于节点B已提交提案的事务标识符的最大值(也就是<1,10>),所以节点C会用DIFF的方式修复数据副本的不一致。并返回差异数据(也就是事务标识符为<1,11>的提案)和NEWLEADER消息给节点B,如图所示.
这里强调一点:节点B已提交提案的最大值,也是节点B最新提案的最大值。因为在ZooKeeper实现种,节点退出跟随者状态时(也就是在进入选举前),所有未提交的提案都会被提交。这是ZooKeeper的设计。
然后,节点B修复不一致数据,返回NEWLEADER消息的确认响应给领导者(即节点C),如图所示.
接着,节点C在接收到来自大多数节点的NEWLEADER消息的确认响应后会将ZAB状态设置为广播状态。在这里,节点C接收到节点B和节点C自己的确认响应,满足大多数确认的要求。所以,在接收到来自节点B的确认响应后,节点C会将自己的ZAB状态设置为广播状态,并发送UPTODATE消息给所有跟随者,通知它们数据同步已经完成了,如图所示。
最后当节点B接收到UPTODATE消息时,它就直到数据同步已经完成,并设置ZAB状态为广播状态,如图所示
注意
在ZooKeeper的代码实现中,处于提交状态的提案是可能会改变的,为什么呢?
-
在ZooKeeper中,一个提案进入提交状态的方式有两种:被复制到大多数节点上和被领导者提交或接收到来自领导者的提交消息(leader.COMMIT)而被提交。
在这种状态下,提交的提案是不会改变的。 -
另外,在ZooKeeper的设计中,节点在退出跟随者状态时(在follower.shutdown()函数中)会将所有本地未提交的提案都提交。需要注意的是,此时提交的提案可能并未被复制到大多数节点上,而且这种设计会导致ZooKeeper中出现处于"提交"状态的提案可能会被删除(也就是接收到领导者的TRUNC消息而删除的提案)的情况。
-
更准确地说,在ZooKeeper中,被复制到大多数节点上地提案最终会被提交,并不会再改变,而只在少数节点存在地提案可能会被提交和不再改变,,也可能会被删除。为了更好地理解,举个具体的例子。
-
如果写请求对应的提案"SET X=1"已经复制到大多数节点上,那么它最终会被提交,之后也不会再改变。也就是说,再没有新的X赋值操作的前提下,不管节点怎么崩溃、领导者如何变更,你查询到的X的值都为1。
-
如果写请求对应的提案"SET X=1"未被复制到大多数节点上,比如在领导者广播消息过程中,领导者崩溃了,那么提案"SET X=1"可能会被复制到大多数节点上提交并不再改变,也可能会被删除。这个行为是未确定的,具体取决于新的领导者是否包含该提案。
-
另外,补充下,在ZAB协议选举出了新的领导者后,该领导者不能立即处理写请求,还需要通过成员发现、数据同步两个阶段进行故障恢复。这是由于ZAB协议的设计决定的,不是所有的共识算法都必须这样,比如通过Raft算法选举出新的领导者后,领导者是可以立即处理写请求的。
相关文章:

分布式与一致性协议之ZAB协议(五)
ZAB协议 ZAB集群如何从故障中恢复 如果我们想把ZAB集群恢复到正常状态,那么新领导者就必须确立自己的领导关系,成为唯一有效的领导者,然后作为主节点"领导"各备份节点一起处理读写请求 如何确立领导关系 前面提到,选…...

计算机毕业设计 | springboot+vue凌云在线阅读平台 线上读书系统(附源码)
1,绪论 随着社会和网络技术的发展,网络小说成为人们茶钱饭后的休闲方式,但是现在很多网络小说的网站都是收费的,高额的收费制度是很多人接受不了的,另外就是很多小说网站都会有大量的弹窗和广告,这极大的影…...

ICode国际青少年编程竞赛- Python-1级训练场-综合训练1
ICode国际青少年编程竞赛- Python-1级训练场-综合训练1 1、 Spaceship.turnLeft() for i in range(2):Spaceship.turnLeft()Spaceship.step(3) Dev.step(-1) Spaceship.step(4) Spaceship.turnLeft() Spaceship.step(3)2、 Spaceship.step() Spaceship.turnLeft() Spaceship.…...

提示词工程入门-使用文心一言4.0-通义千问-GPT4-Claude3通用提示技巧测试
提示词工程基础🚀 在了解完了大语模型的基本知识,例如API的使用多轮对话,流式输出,微调,知识向量库等知识之后,接下来需要进一步补足的一个大块就是提示词工程,学习和了解提示词工程除了基本的提…...
损失函数详解
1.损失函数 是一种衡量模型与数据吻合程度的算法。损失函数测量实际测量值和预测值之间差距的一种方式。损失函数的值越高预测就越错误,损失函数值越低则预测越接近真实值。对每个单独的观测(数据点)计算损失函数。将所有损失函数(loss function…...

算法提高之树的中心
算法提高之树的中心 核心思想:树形dp 换根dp 每个点作为根节点 找其子树的最大距离和父节点的最大距离 dfs1:求子树对于当前根节点的最大距离和次大距离 求次大距离原因:如果当前节点是其父节点子树的最大路径上的点,最大距离不…...

【Java基础】面向对象是什么
面向对象和面向过程的对比 类和对象 class Car{} 是描述对象(车)的类,属于引用数据类型用来描述对象具有的属性(变量)和行为(函数),属于概念模型 Car baomanew Car(); 对象需要由类来创建对象具备了类中定义的属性和行为 对象…...

家用洗地机应该怎么选?哪个牌子好?市场上主流洗地机品牌推荐
洗地机的出现,让越来越多的家庭享受清洁的过程,给人们腾出来更多的时间陪伴家人和休息。但是在选购一台洗地机前,大家多多少少肯定有些疑问,洗地机到底实不实用?好不好用?能扫干净吗?还有哪些好…...
python Django REST framework允许你根据API的版本提供不同的行为或数据
在Django REST framework中,版本控制是一个重要的功能,它允许你根据API的版本提供不同的行为或数据。以下是如何在Django REST framework中设置API版本控制的几种方法: 1. 使用URL路径参数 你可以通过URL路径中的参数来指定API的版本。例如: python复制 # urls.py from …...
unity给物体添加可以包裹所有子物体的BoxCollider
代码如下可直接调用 MeshTool.SpawnCollider(mode);using UnityEngine;public class MeshTool {public static Bounds SpawnCollider(Transform target){Vector3 pMax Vector3.zero;Vector3 pMin Vector3.zero;Vector3 center Vector3.zero;Vector3 oldPos target.transfor…...

2024五一数学建模A题思路代码与论文分析
2024五一数学建模A题完整代码和成品论文获取↓↓↓↓↓ https://www.yuque.com/u42168770/qv6z0d/gyoz9ou5upvkv6nx?singleDoc# 2024五一数学建模A题钢板最优切割路径问题需要建立的模型和算法: 图论 最短路径算法(Dijkstra算法、Floyd算法等) 动态规划 网格化离散建模 …...

ICode国际青少年编程竞赛- Python-1级训练场-基础训练2
ICode国际青少年编程竞赛- Python-1级训练场-基础训练2 1、 a 4 # 变量a存储的数字是4 Dev.step(a) # 因为变量a的值是4,所以Dev.step(a)就相当于Dev.step(4)2、 a 1 # 变量a的值为1 for i in range(4):Dev.step(a)Dev.turnLeft()a a 1 # 变量a的值变为…...

科技控必看!让你轻松成为机器人领域达人
科技控们注意了!你是不是经常对机器人技术充满无限的好奇,却又因为缺乏合适的渠道而难以深入了解和亲身体验呢?别担心,BFT机器人,正是你探索机器人世界的绝佳之地! 在这里,你将发现一个充满惊喜…...

Linux进程——Linux下常见的进程状态
前言:在进程学习这一块,我们主要学习的就是PCB这个进程控制块,而PBC就是用来描述进程的结构体,而进程状态就是PCB结构体中的一个变量。 本篇主要内容: 操作系统中的进程状态Linux下的进程状态 在开始之前,我…...
TCP长连接短链接
1、短连接 短连接是指通讯双方有数据交互时,就建立一个连接,数据发送完成后,则断开此连接,即每次连接只完成一项业务的发送。 2、长连接 长连接是指在一个连接上可以连续发送多个数据包,在连接保持期间,…...
代码随想录35期Day33-Java
Day33题目 LeetCode1005:K 次取反后最大化的数组和 核心思想:每次取反都取反最小的。如果有负数,则一直取反最小的负数,如果没有就取反正数。取反次数只需要看是奇数还是偶数。偶数则正数序列不变,奇数则最小的变成负数 class …...

PMP考试没过怎么办?如何补考?(附复核流程)
最近刷小红书,看很多人都在晒PMP通过的成绩截图,一方面为大家开心,终于拿到了期盼已久的PMP,但同时也有宝子发挥失常没通过考试,所以这期针对没考过的宝子们,出一期复盘文章,无论结果如何&#…...

自主实现Telnet流量抓取
自主实现Telnet流量抓取 根据测试需求,需要抓取Telnet流量包,使用wireshark Python(socket、telnetlib库)实现 实现代码 主要此处有坑, 根据协议规则,wireshark 默认端口为23 的是Telnet协议࿰…...
以瓦片地图为底图添加图表,保留拖拽功能
1、问题1 在地图上覆盖一个容器层,容器层上的内容显示不出来如何解决? 原因:堆叠指数问题 解决方案:绝对定位后,提升其z-index值即可 2、问题2 在地图上覆盖一个容器层,影响了地图拖拽,如何…...
Windows cmd bat之特殊符号及变量
cmd 常用变量 bat批处理常用命令 %1~%9表示拖入文件(%0以外的输入文件),%0表示批处理文件本身 %0~%1字母意思基本相同,不区分大小写 ::打印当前窗口地址 echo “%cd%” %0 获取当前文件路径 %~d0 …...
HTML 语义化
目录 HTML 语义化HTML5 新特性HTML 语义化的好处语义化标签的使用场景最佳实践 HTML 语义化 HTML5 新特性 标准答案: 语义化标签: <header>:页头<nav>:导航<main>:主要内容<article>&#x…...
【Java学习笔记】Arrays类
Arrays 类 1. 导入包:import java.util.Arrays 2. 常用方法一览表 方法描述Arrays.toString()返回数组的字符串形式Arrays.sort()排序(自然排序和定制排序)Arrays.binarySearch()通过二分搜索法进行查找(前提:数组是…...

大数据零基础学习day1之环境准备和大数据初步理解
学习大数据会使用到多台Linux服务器。 一、环境准备 1、VMware 基于VMware构建Linux虚拟机 是大数据从业者或者IT从业者的必备技能之一也是成本低廉的方案 所以VMware虚拟机方案是必须要学习的。 (1)设置网关 打开VMware虚拟机,点击编辑…...
Spring Boot面试题精选汇总
🤟致敬读者 🟩感谢阅读🟦笑口常开🟪生日快乐⬛早点睡觉 📘博主相关 🟧博主信息🟨博客首页🟫专栏推荐🟥活动信息 文章目录 Spring Boot面试题精选汇总⚙️ **一、核心概…...
【C语言练习】080. 使用C语言实现简单的数据库操作
080. 使用C语言实现简单的数据库操作 080. 使用C语言实现简单的数据库操作使用原生APIODBC接口第三方库ORM框架文件模拟1. 安装SQLite2. 示例代码:使用SQLite创建数据库、表和插入数据3. 编译和运行4. 示例运行输出:5. 注意事项6. 总结080. 使用C语言实现简单的数据库操作 在…...

MySQL 8.0 OCP 英文题库解析(十三)
Oracle 为庆祝 MySQL 30 周年,截止到 2025.07.31 之前。所有人均可以免费考取原价245美元的MySQL OCP 认证。 从今天开始,将英文题库免费公布出来,并进行解析,帮助大家在一个月之内轻松通过OCP认证。 本期公布试题111~120 试题1…...
CMake控制VS2022项目文件分组
我们可以通过 CMake 控制源文件的组织结构,使它们在 VS 解决方案资源管理器中以“组”(Filter)的形式进行分类展示。 🎯 目标 通过 CMake 脚本将 .cpp、.h 等源文件分组显示在 Visual Studio 2022 的解决方案资源管理器中。 ✅ 支持的方法汇总(共4种) 方法描述是否推荐…...

有限自动机到正规文法转换器v1.0
1 项目简介 这是一个功能强大的有限自动机(Finite Automaton, FA)到正规文法(Regular Grammar)转换器,它配备了一个直观且完整的图形用户界面,使用户能够轻松地进行操作和观察。该程序基于编译原理中的经典…...

Kafka入门-生产者
生产者 生产者发送流程: 延迟时间为0ms时,也就意味着每当有数据就会直接发送 异步发送API 异步发送和同步发送的不同在于:异步发送不需要等待结果,同步发送必须等待结果才能进行下一步发送。 普通异步发送 首先导入所需的k…...
JavaScript 数据类型详解
JavaScript 数据类型详解 JavaScript 数据类型分为 原始类型(Primitive) 和 对象类型(Object) 两大类,共 8 种(ES11): 一、原始类型(7种) 1. undefined 定…...