当前位置: 首页 > news >正文

分布式之Raft共识算法分析

写在前面

在分布式之Paxos共识算法分析 一文中我们分析了paxos算法,知道了其包括basic paxos和multi paxos,并了解了multi paxos只是一种分布式共识算法的思想,而非具体算法,但可根据其设计具体的算法,本文就一起来看下其一种具体的实现算法raft,这也是当前中心化架构分布式系统使用最多的一种分布式共识算法了,下面我们就一起看下吧!

1:raft提供了哪些内容

在multi paxos的描述中有一个霸道总裁的角色leader,因此在raft中就定义了leader的选举策略。除此之外还定义了日志复制策略,成员变更。接下来我们分别看下这三部分内容。

2:leader选举

首先我们先来看下raft中节点的角色,包括领导者,跟随者(非leader大部分时间所处的状态),候选者(竞选leader时所处的状态),另外每个节点还有一个任期编号的属性,代表当前集群的leader是第几任leader(可用于处理多leader场景,以及leader选举投票确定是否投票),任期编号默认为0,如下图:

在这里插入图片描述

在系统初始状态,所有节点所处的状态都是跟随者,并且每个节点都有leader心跳消息的超时时间,该超时时间是随机的,避免多节点同时到期并竞选leader,导致无法快速选举leader的问题。如下节点A,节点B,节点C,超时时间分别是150ms,200ms,300ms:

在这里插入图片描述

很明显,节点A会先超时,转换角色为候选人并将自己的任期编号+1变为1(其认为主节点故障,需要产生新的leader,因此任期编号+1),先向自己投1票,并向其他节点发送申请成为leader消息,如下图:

在这里插入图片描述

其他节点发现自己的任期都小于1,并且自己在term=1都还没有投过票(一个任期只能投一票,即某任期一旦投过票,在收到相同任期申请成为leader的请求则忽略或投拒绝票),因此会投出自己唯一的一票,如下:

在这里插入图片描述

之后节点A获取了3票赞成票,超过了3个节点的半数,因此成为leader,如下:

在这里插入图片描述

接着leader就会周期性的给其他节点发送心跳消息,防止其他节点的leader心跳超时时间到时,并篡权,如下图:

在这里插入图片描述

以上过程源码参考这里 ,运行过程如下图:

在这里插入图片描述

补充下其他的规则:

1:领导者周期性地向所有跟随者发送心跳消息(即不包含日志项的日志复制 RPC 消息),通知大家我是领导者,阻止跟随者发起新的选举。
2:如果在指定时间内,跟随者没有接收到来自领导者的消息,那么它就认为当前没有领导者,推举自己为候选人,发起领导者选举。
3:在一次选举中,赢得大多数选票的候选人,将晋升为领导者。
4:在一个任期内,领导者一直都会是领导者,直到它自身出现问题(比如宕机),或者因为网络延迟,其他节点发起一轮新的选举。
5:在一次选举中,每一个服务器节点最多会对一个任期编号投出一张选票,并且按照“先来先服务”的原则进行投票。比如节点 C 的任期编号为 3,先收到了 1 个包含任期编号为 4 的投票请求(来自节点 A),然后又收到了 1 个包含任期编号为 4 的投票请求(来自节点 B)。那么节点 C 将会把唯一一张选票投给节点 A,当再收到节点 B 的投票请求 RPC 消息时,对于编号为 4 的任期,已没有选票可投了。
6:日志完整性高的跟随者(也就是最后一条日志项对应的任期编号值更大,索引号更大),拒绝投票给日志完整性低的候选人。比如节点 B 的任期编号为 3,节点 C 的任期编号是 4,节点 B 的最后一条日志项对应的任期编号为 3,而节点 C 为 2,那么当节点 C 请求节点 B 投票给自己时,节点 B 将拒绝投票。

2.1:常见问题

2.1.1:如何知道选票超过半数

总节点数是固定的,已知的,进行简单数学运算即可。

2.1.2:raft存在的问题

leader的单点问题,以及由此带来的写数据性能瓶颈问题。节点较多时,leader的心跳消息有较高的通信成本。节点较多时,选主获得半数投票时间长,集群不可用时间长。

2.1.3:所有节点都可能成为leader吗?

不是的,必须当前节点的日志完整性高于超过半数的节点(这样才可能获得半数以上选票),但这里并不带代表这些节点不能成为candidate并发起选举,只是说就算发起选举了,最终也会选举失败而已。

2.1.4:leader会一直是leader吗?

如果是机器和网络一直正常的话,是的,但是实际环境并不会,根据chubby团队观察,一个leader的任期大概是在几天左右。

2.1.5:如果集群重启,集群状态如任期编号会清0吗?

不会的,这些信息是持久化存储的,重启后,需要将集群恢复到重启前的状态。

2.1.6:如果某轮leader选举失败,下一轮选举任期编号会+1吗?

会的,因为一个任期一个节点只有一张选票,如果不+1的话,将无法在新一轮投出选票。

2.1.7:如果一个节点孤立,导致leader选举一直失败,任期编号不断增大,则当其回到集群会影响集群吗?

不会,因为当其回到集群后,别的节点发现自己的任期编号小于其任期编号,则会更新自己的任期编号为其任期编号,并且因为自己的日志完整性高于其,所以也不会给其投出选票,其也成不了leader,所以,不会有影响。

2.1.8:心跳随机超时时间怎么确定,如何查看?

这就是属于编码实现问题了,一般设置在某个时间范围内,至于如何查看也是和具体程序实现有关。

2.1.9:raft算法中只有leader才能接收读请求吗?

raft算法本身没有要求,如果是要求最终一致性,则可以允许非leader读取,比如zookeeper就是如此,直接响应本地数据。

2.1.10:如果集群正在选主此时集群还能正常工作吗?

写请求无法执行,需要客户端重试。读请求如果是允许非leader处理的话,则正常,否则也需要重试,等到选主完成。

2.1.11:因为leader心跳超时,导致选举出新leader,当老leader收到新leader心跳时会如何处理?

更新自己的状态为跟随者,并使用新leader的任期编号更新自己的任期编号。

3:日志复制

可以认为为日志即数据,日志由日志项组成,且日志必须是连续的,这不同于multi-paxos。一个日志项包含如下3部分内容:

指令:用户发送的指令,如set x 10这种
任期编号:创建该条日志项leader的任期编号,相当于是给数据标识版本
索引值:单调递增的索引编号,用来标识日志项

如下图:

在这里插入图片描述

日志同步过程如下:

1:leader生成日志条目,发送日志同步RPC消息复制日志条目到其他节点
2:当超过半数的节点返回复制成功消息后,将日志项应用到状态机(通过状态机记录日志项已经写入成功),然后返回成功消息给客户端

这里需要注意,leader在收到了大多数节点写入成功消息后,并不会再次发送提交日志条目消息到其他节点,也就是两阶段提交变为了一阶段提交,这里提交的消息并不是不发了,而只是会随着后续的同步日志消息,或者是leader的心跳消息,来同步给其他节点,这样就可以减少一半的网络交互开销,可通过下图对比查看:

在这里插入图片描述

假设节点A,节点B,节点C,节点D,其中节点A为leader,任期编号为9,索引编号是88,发送的指令是set x=90,即要发送的日志段是(88,9,set x=90),则该过程如下图:

在这里插入图片描述

源码实现参考这里 ,运行效果如下图:

在这里插入图片描述

3.1:如何实现日志一致性

如果节点一直处于正常状态,节点能够正常的复制来自leader的日志段,但是如果是发生了宕机,重启等故障后follower出现了和leader的日志不一致,这种情况raft算法是怎么实现恢复一致的呢?我们一起来看下。首先看以下的点:

1:数据绝对以leader的为准
2:leader可以覆盖和删除follower不一致的数据
3:leader的数据不会被覆盖和删除

为了处理可能出现的日志一致性问题,leader在发送日志同步消息时,除了携带日志段外,还会携带当前日志段的上一个日志段的索引号以及对应的任期编号,如下要发送的索引号就是7,任期编号就是4:

在这里插入图片描述

当follower收到后会对比自己的最新的日志段是否匹配二者,如果匹配的话则接受日志段,否则返回失败,返回失败后leader继续向前找,继续发送,直到follower接受,则从接收的位置发送后续日志段,覆盖follower的日志段,从而使得和leader的日志保持一致,可参考下图:

在这里插入图片描述

3.2:常见问题

3.2.1:如果超过半数follower都收到日志段但是leader还未应用状态到状态机,此时leader挂掉,数据会丢失吗?

不会,因为最终当选为新leader的node是有该未提交日志段的,然后发现超过半数的node都有该日志段(老leader肯定是有的,所以这里的半数要包括老leader),则会提交日志段,并在后续发送消息给其它follower也提交该日志段。

3.2.2:如何保证客户端写操作请求到leader?

一般有两种方式(假定收到请求的节点是follower),1:follower充当代理角色,转发请求给leader 2:follower返回leader地址给客户端,客户端再次向leader发起写请求。

4:成员变更

成员变更是指通过新增节点来增加副本数,成员变更的一个问题就是集群短时间内处于不稳定状态,而可能会导致出现2个leader的情况,这就违背了leader唯一性的原则,而导致出现这个问题的原因一般都是网络分区,如下是有3个节点的集群:

在这里插入图片描述

此时集群配置是[A,B,C],现在加入2个节点D,E,如下图:

在这里插入图片描述

假定集群稳定前的某一刻发生了网络分区,AB处于一个分区,CDE处于一个分区,如下图:

在这里插入图片描述

此时新配置是[A,B,C,D,E],则新配置的大多数就是3,如上图就产生了新leader C,而老配置是[A,B,C],则老配置的大多数就是2,产生了新leader A,此时就出现了2个leader A 和 C,这样就有问题了。raft解决这个问题的方式有联合共识和单节点变更,联合共识是最初的方案,但因为过于复杂,所以后续就有了单节点变更的方案,这种方案可以解决因为一次添加过多节点导致出现分区时同时满足新旧大多数而破坏leader唯一性的问题。接下来我们看下单节点变更的方案,假设依然是3个节点ABC,如下:

在这里插入图片描述

首先添加一个节点D:

在这里插入图片描述

此时老配置是[A,B,C],大多数是2,新配置是[A,B,C,D],大多数是3,只有总节点数至少为5,才能同时满足新旧配置的大多数,而此时节点数是4,所以在出现网络分区不会满足>1个leader的情况,接着我们来增加节点E:

在这里插入图片描述

此时老配置是[A,B,C,D],大多数是3,新配置是[A,B,C,D,E],大多数是3,要想满足新旧配置的大多数,则至少需要有6个节点,而此时只有5个节点,所以不管出现何种情况的分区也不可能出现>1个leader的情况。

写在后面

小结

本文一起看了raft共识算法对分布式系统中leader选举,日支复制,成员变更3个主要问题提供的解决思路。希望本文能够帮助到你。

参考文章列表

分布式之Paxos共识算法分析 。

分布式理论之分布式选举 。

The Secret Lives of Data 。

什么是状态机?一篇文章就够了 。

状态机分析 。

相关文章:

分布式之Raft共识算法分析

写在前面 在分布式之Paxos共识算法分析 一文中我们分析了paxos算法,知道了其包括basic paxos和multi paxos,并了解了multi paxos只是一种分布式共识算法的思想,而非具体算法,但可根据其设计具体的算法,本文就一起来看…...

数据库——范式

目录 一、概念 二、各范式 第一范式 第二范式 第三范式 BC范式 第四范式 第五范式(略) 一、概念 基本概念 关系:通常一个关系对应一张表;元组:一行;属性:一列;码&#xff1…...

Geospatial Data Science(2):Geospatial Data in Python

Geospatial Data Science(2):Geospatial Data in Python PART 1: 检查数据 1.1 Imports import geopandas as gpd # for geospatial data handling import osmnx # for handling data from OpenStreetMap (osm) with the help of networkX (nx) import contextily as cx # f…...

16.hadoop系列之MapReduce之MapTask与ReduceTask及Shuffle工作机制

1.MapTask工作机制 以上内容我们之前文章或多或少介绍过,就已网络上比较流行的该图进行理解学习吧 MapTask分为五大阶段 Read阶段Map阶段Collect阶段溢写阶段Merge阶段 2.ReduceTask工作机制 ReduceTask分为三大阶段 Copy阶段Sort阶段Reduce阶段 3.ReduceTask并…...

java 面试过程中遇到的几个问题记录20230220

微服务注册中心的作用微服务注册中心的作用是协调和管理微服务实例的注册和发现。它充当了服务注册表,可以维护服务实例的元数据,例如服务名称、IP 地址和端口号等。当一个微服务启动时,它会向注册中心注册自己的元数据,以使其他服…...

面试题:【数据库三】索引简述

目录 一、索引是什么 二、索引规则 三、索引失效场景 一、索引是什么 索引是帮助Mysql高效获取数据的【数据结构】索引存储在文件系统中索引的文件存储形式与存储引擎相关 mysql有三种存储引擎 InnoDBMyISAMMEMORY索引文件的结构 Hash Hash索引底层是哈希表,哈希…...

数据库必知必会:TiDB(12)TiDB连接管理

数据库必知必会:TiDB(12)TiDB连接管理TiDB连接管理TiDB的连接特性连接TiDBMySQL命令行客户端图形界面客户端连接其他连接方式写在后面TiDB连接管理 TiDB的连接特性 TiDB Server主要负责接收用户的会话请求,接收SQL并负责SQL语句…...

电源大事,阻抗二字

作者:一博科技高速先生成员 姜杰PCB设计时,我们通常会控制走线的特征阻抗;电源设计时,又会关注电源分配系统(PDN)的交流阻抗,虽然都是阻抗,一个是信号的通道要求,一个是电…...

ASE20N60-ASEMI的MOS管ASE20N60

编辑-Z ASE20N60在TO-247封装里的静态漏极源导通电阻(RDS(ON))为0.4Ω,是一款N沟道高压MOS管。ASE20N60的最大脉冲正向电流ISM为80A,零栅极电压漏极电流(IDSS)为10uA,其工作时耐温度范围为-55~150摄氏度。ASE20N60功耗…...

nginx 代理01(持续更新)

1、如果请求是post,而且请求原是188.188.3.171,处理方式403 if ($request_method ~* "POST") # $request_method 等同于request的method,通常是“GET”或“POST” # 如果访问request的method值为POST则返回“o” {set…...

初阶C语言——操作符【详解】

文章目录1.算术操作符2.移位操作符2.1 左移操作符2.2 右移操作符3.位操作符按位与按位或按位异或4.赋值操作符复合赋值符5.单目操作符5.1单目操作符介绍6.关系操作符7.逻辑操作符8.条件操作符9.逗号表达式10.下标引用、函数调用和结构成员11表达式求值11.1 隐式类型转换11.2算术…...

37k*16 薪,年后直接上岗,3年自动化测试历经3轮面试成功拿下阿里Offer....

前言 转眼过去,距离读书的时候已经这么久了吗?,从18年5月本科毕业入职了一家小公司,到现在快4年了,前段时间社招想着找一个新的工作,前前后后花了一个多月的时间复习以及面试,前几天拿到了阿里…...

利用Rust与Flutter开发一款小工具

1.起因 起因是年前看到了一篇Rust iOS & Android|未入门也能用来造轮子?的文章,作者使用Rust做了个实时查看埋点的工具。其中作者的一段话给了我启发: 无论是 LookinServer 、 Flipper 等 Debug 利器,还是 Flutt…...

零入门kubernetes网络实战-16->使用golang给docker环境下某个容器里添加一个额外的网卡

《零入门kubernetes网络实战》视频专栏地址 https://www.ixigua.com/7193641905282875942 本篇文章视频地址(稍后上传) 上一篇文章,我们使用了golang在veth pair链接的网络命名空间里添加了网卡, 本篇文章,我尝试,在docker环境下…...

音频信号处理笔记(二)

文章目录1.1.3 过零率1.1.4 谱质心和子带带宽1.1.5 短时傅里叶分析法1.1.6 小波变换相关课程: 音频信号处理及深度学习教程傅里叶分析之掐死教程(完整版)更新于2014.06.06 - 知乎 (zhihu.com)1.1.3 过零率 过零率:是一个信号符号…...

钓鱼网站+bypassuac提权

本实验实现1 :要生成一个钓鱼网址链接,诱导用户点击,实验过程是让win7去点击这个钓鱼网站链接,则会自动打开一个文件共享服务器的文件夹,在这个文件夹里面会有两个文件,当用户分别点击执行后,则…...

合并两个有序链表——递归解法

题目描述21. 合并两个有序链表难度简单2922收藏分享切换为英文接收动态反馈将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 示例 1:输入:l1 [1,2,4], l2 [1,3,4]输出:[1,1,2,3,4,4]示例…...

ADRC自抗扰控制总结

目录 前言 1.ADRC形式 1.1形一 1.2形二 2.被控对象 3.仿真分析 3.1仿真模型 3.2仿真结果 4.学习问题 前言 前面的3篇文章依次介绍了微分跟踪器TD、状态观测器ESO和非线性状态误差反馈NLSEF三部分内容,至此ADRC的结构已经介绍完毕,现在对分块学习…...

3年工作之后是不是还在“点点点”,3年感悟和你分享....

经常都有人问我软件测试前景怎么样,每年也都帮助很多朋友做职业分析和学习规划,也很欣慰能够通过自己的努力帮到一些人进入到大厂。 2023年软件测试行业的发展现状以及未来的前景趋势 最近很多测试人在找工作的时候,明显的会发现功能测试很…...

【自动化测试】web自动化测试验证码如何测?如何处理验证码问题?解决方案......

目录:导读前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结(尾部小惊喜)前言 在对安全性有要求的…...

Windows开机自动启动中间件

WinSW(Windows Service Wrapper 是一个开源的 Windows 服务包装器,它可以帮助你将应用程序打包成系统服务,并实现开机自启动的功能。 一、下载 WinSW 下载 WinSW-x64.exe v2.12.0 (⬇️ 更多版本下载) 和 sample-minimal.xml 二、配置 WinS…...

FMC STM32H7 SDRAM

如何无痛使用片外SDRAM? stm32 已经成功初始化了 STM32H7 上的外部 SDRAM(32MB) 如何在开发中无痛使用SDRAM 使它像普通 RAM 一样“自然地”使用? [todo] 重要 MMT(Memory Management Tool) of STM32CubeMx The Memory Management Tool (MMT) disp…...

AI 时代下语音与视频伪造的网络安全危机

引言 在人工智能技术的推动下,语音合成、视频生成等技术取得了突破性进展,Deepfake、AI 语音克隆等工具让语音和视频伪造变得愈发简单且逼真。这些技术在娱乐、影视等领域带来便利的同时,也被不法分子利用,引发了一系列网络安全问…...

我爱学算法之—— 前缀和(中)

一、724. 寻找数组的中心下标 题目解析 这道题,给定数组nums,要求我们找出这个数组的中心下标。 **中心下标:**指左侧所有元素的和等于右侧所有元素的和。 如果存在多个中心数组下标,就返回最左侧的中心数组下标。 算法思路 暴…...

Python爬虫:trafilatura 的详细使用(快速提取正文和评论以及结构,转换为 TXT、CSV 和 XML)

更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 一、trafilatura 概述1.1 trafilatura介绍1.2 亮点特色1.3 安装二、基本使用2.1 从URL直接提取内容2.2 输出格式控制2.3 从HTML字符串提取2.4 使用命令行工具三、高级功能3.1 全局设置3.2 提取参数定制3.3 多线程批量处…...

day50 随机函数与广播机制

目录 一、随机张量的生成 1.1 torch.randn() 函数 1.2 其他随机函数 1.3 输出维度测试 二、广播机制 2.1 广播机制的规则 2.2 加法的广播机制 二维张量与一维向量相加 三维张量与二维张量相加 二维张量与标量相加 高维张量与低维张量相加 2.3 乘法的广播机制 批量…...

webpack其余配置

webpack搭建本地服务器 首先是要安装一个webpack-dev-server npm install webpack-dev-server -D 安装后在package.json中添加: {"name": "babel_core_demo","version": "1.0.0","main": "index.js"…...

分形几何在医学可视化中的应用:从理论到Python实战

分形几何在医学可视化中的应用:从理论到Python实战 前言 分形几何作为描述自然界复杂结构的数学工具,正通过其自相似性和分数维度特性,革新医学影像分析领域。本文系统阐述分形几何在医学影像中的创新应用,涵盖从图像预处理、分…...

计算机二级Python考试的核心知识点总结

以下是计算机二级Python考试的核心知识点总结,结合高频考点和易错点分类整理: 1. **数据类型与运算** ▷ 不可变类型:int, float, str, tuple(重点区分list与tuple) ▷ 运算符优先级:** > * /…...

Go深入学习延迟语句

1 延迟语句是什么 编程的时候,经常会需要申请一些资源,比如数据库连接、文件、锁等,这些资源需要再使用后释放掉,否则会造成内存泄露。但是编程人员经常容易忘记释放这些资源,从而造成一些事故。 Go 语言直接在语言层…...