分布式之Raft共识算法分析

news2024/9/21 3:25:01

写在前面

在分布式之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 。

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

状态机分析 。

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

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

相关文章

SORT与DeepSORT简介

一、MOT( mutil-object tracking)步骤 在《DEEP LEARNING IN VIDEO MUTIL-OBJECT TEACKING: A SURVEY》这篇基于深度学习多目标跟踪综述中,描绘了MOT问题的四个主要步骤 1.跟定视频原始帧 2.使用目标检测器如Faster-rcnn, YOLO, SSD等进行检测,获取目标…

vue 3.0 Vue Router导航守卫的使用

目录前言:安装路由快速使用1. 创建路由模块2.规定路由模式3.使用路由规则4.声明路由链接和占位符5.重定向路由6.嵌套路由7.路径参数8. 声明式和编程式导航8.1 导航到不同的位置8.2 替换当前位置8.3 路由历史9.导航守卫9.1 全局前置守卫9.2全局路由守卫的语法参数9.3…

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

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

关于Java的深拷贝和浅拷贝

文章目录1.拷贝的引入1.1引用拷贝1.2对象拷贝2.深拷贝与浅拷贝2.1浅拷贝2.2深拷贝1.拷贝的引入 1.1引用拷贝 创建一个指向对象的引用变量的拷贝 Teacher teacher new Teacher("Taylor",26); Teacher otherteacher teacher; System.out.println(teacher); System…

vim常用命令

vim常用三种模式 命令模式(Command mode) 插入模式(Insert mode) 末行模式(Last line mode) (一)进入命令模式 vi 或者 vim(二)命令模式 -> 插入模式 &…

服务器部署流程与经验记录

服务器部署流程1.项目部署1.1 重置实例密码1.2 配置安全组规则1.3 远程连接服务器1.4 安装所需软件1.5 安装Tomcat1.6 配置宝塔安全组1.7 导入数据库和项目2. 域名注册3. 网站备案1.项目部署 1.1 重置实例密码 1.2 配置安全组规则 1.3 远程连接服务器 使用VNC远程连接&#…

实用调试技巧——“C”

各位CSDN的uu们你们好呀,今天小雅兰的内容是实用调试技巧,其实小雅兰一开始,也不知道调试到底是什么,一遇到问题,首先就是观察程序,改改这里改改那里,最后导致bug越修越多,或者是问别…

51单片机——定时器中断实验,小白讲解,相互学习

定时器介绍 1,CPU时序的有关知识 震荡周期:为单片机提供定时信号的震荡源的周期(晶振周期或外加震荡周期)。状态周期:2个震荡周期为1个状态周期,用S表示。震荡周期又称S周期或时钟周期。机器周期&#xff…

Java-多线程并发-线程的实现、调度和状态转换

线程的实现 线程是比进程更轻量级的调度执行单位,线程的引入,可以把一个进程的资源分配和执行调度分开,各个线程既可以共享进程资源( 内存地址、文件I/O等 ),又可以独立调度( 线程是CPU调度的基本单位 )。 Java语言则提供了在不…

300行代码手写spring初体验v1.0版本

70%猜想30%验证 spring:IOC 、DI、AOP、MVC MVC作为入口 web.xml 内部依赖一个DispathcheServlet这样一个接口 先来说一下springMVC的一些基础知识 整体的一个思路: 在web.xml里面进行了一个核心servlet的一个配置 核心就是这个DispatcherServlet …

用列表y表示序列x中每个元素是否被选中 根据列表y返回序列x中被选中的元素 itertools.compress(x,y)

【小白从小学Python、C、Java】 【计算机等级考试500强双证书】 【Python-数据分析】 用列表y表示序列x中每个元素是否被选中 根据列表y返回序列x中被选中的元素 itertools.compress(x,y) [太阳]选择题 以下关于python代码表述错误的一项是? from itertools import compress …

2022年全国职业院校技能大赛(中职组)网络安全竞赛试题A模块(4)

目录 二、竞赛注意事项 (本模块20分) 一、项目和任务描述: 二、服务器环境说明 三、具体任务(每个任务得分以电子答题卡为准) A-1任务一 登录安全加固(Windows) 1.密码策略 a.更改或创建…

未来的城市:智慧城市定义、特征、应用、场景

智慧城市是通过连接一个地区的物理、经济和社会基础设施,以创新、有效和高效的方式应用和实施技术来发展城市的概念,以改善服务并实现更好的生活质量。智慧城市是一个将信息和通信技术融入日常治理的城市区域,旨在实现效率、改善公共服务、增…

Kafka优化篇-压测和性能调优

简介 Kafka的配置详尽、复杂,想要进行全面的性能调优需要掌握大量信息,这里只记录一下我在日常工作使用中走过的坑和经验来对kafka集群进行优化常用的几点。 Kafka性能调优和参数调优 性能调优 JVM的优化 java相关系统自然离不开JVM的优化。首先想到…

消息队列(kafka简单使用)

Dubbo远程调用的性能问题Dubbo调用普遍存在于我们的微服务项目中这些Dubbo调用全部是同步的操作这里的"同步"指:消费者A调用生产者B之后,A的线程会进入阻塞状态,等待生产者B运行结束返回之后,A才能运行之后的代码Dubbo消费者发送调用后进入阻塞状态,这个状态表示该线…

再学C语言39:指针操作(2)

在编写处理int这样的基本类型的函数时,可以向函数传递int数值,也可以传递指向int的指针 通常直接传递int数值,只有需要在函数中修改该值时,才传递指针 对于处理数组的函数,只能传递指针,这样能使程序效率…

如何运行YOLOv6的代码实现目标识别?

YOLOv6是由美团视觉团队开发的1.环境配置我们先把YOLOv6的代码clone下来git clone https://github.com/meituan/YOLOv6.git安装一些必要的包pip install pycocotools2.0作者要求pytorch的版本是1.8.0,我的环境是1.7.0,也是可以正常运行的pip install -r requirement…

C#服务号推送微信公众号模板消息

一、准备工作微信公众平台:https://mp.weixin.qq.com/申请测试账号:https://mp.weixin.qq.com/debug/cgi-bin/sandboxinfo?actionshowinfo&tsandbox/index微信推送消息模板不需要发布服务器,也不需要填写授权回调域名,只需要…

【Vagrant】下载安装与基本操作

文章目录概述软件安装安装VirtualBox安装Vagrant配置环境用Vagrant创建一个VMVagrantfile文件配置常用命令概述 Vagrant是一个创建虚拟机的技术,是用来创建和管理虚拟机的工具,本身自己并不能创建管理虚拟机。创建和管理虚拟机必须依赖于其他的虚拟化技…

11 OpenCV图像识别之人脸识别

文章目录1 Eigenfaces1.1 建模流程1.2 示例代码2 Fisherfaces2.1 建模流程2.2 示例代码3 Local Binary Histogram3.1 建模流程3.2 示例代码OpenCV 提供了三种人脸识别方法:Eigenfaces Eigenfaces是一种基于PCA(Principal Component Analysis&#xff0c…