Raft算法详解

Raft算法属于Multi-Paxos算法,它是在Multi-Paxos思想的基础上,做了一些简化和限制,比如增加了日志必须是连续的,只支持领导者、跟随者和候选人三种状态,在理解和算法实现上都相对容易许多

从本质上说,Raft算法是通过一切以领导者为准的方式,实现一系列值的共识和各节点日志的一致

1、领导者选举

1)、成员身份

Raft算法支持领导者(Leader)、跟随者(Follower)和候选人(Candidate)3种状态:

  • 跟随者:接收和处理来自领导者的消息,当等待领导者心跳信息超时的时候,就主动站出来,推荐自己当候选人
  • 候选人:候选人将向其他节点发送请求投票(RequestVote)RPC消息,通知其他节点来投票,如果赢得了大多数选票,就晋升当领导者
  • 领导者:负责处理写请求、管理日志复制和不断地发送心跳信息,通知其他节点“我是领导者,我还活着,你们现在不要发起新的选举,找个新领导者来替代我”

Raft算法是强领导者模型,集群中只能有一个领导者

2)、选举领导者的过程

在初始状态下,集群中所有的节点都是跟随者状态

watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQwMzc4MDM0,size_16,color_FFFFFF,t_70#pic_center

Raft算法实现了随机超时时间的特性,每个节点等待领导者心跳信息的超时时间间隔是随机的。上图中,集群中没有领导者,而节点A的等待超时时间最小,它会最先因为没有等到领导者的心跳信息,发生超时

这时,节点A增加自己的任期编号,并推举自己为候选人,先给自己投上一张选票,然后向其他节点发送请求投票RPC消息,请它们选举自己为领导者

watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQwMzc4MDM0,size_16,color_FFFFFF,t_70#pic_center

如果其他节点接收到候选人A的请求投票RPC消息,在编号为1的这届任期内,也还没有进行过投票,那么它将把选票投给节点A,并增加自己的任期编号

watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQwMzc4MDM0,size_16,color_FFFFFF,t_70#pic_center

如果候选人在选举超时时间内赢得了大多数的选票,那么它就会成为本届任期内新的领导者

watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQwMzc4MDM0,size_16,color_FFFFFF,t_70#pic_center

节点A当选领导者后,它将周期性地发送心跳消息,通知其他服务器我是领导者,阻止跟随者发起新的选举

watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQwMzc4MDM0,size_16,color_FFFFFF,t_70#pic_center

3)、节点间如何通讯?

在Raft算法中,服务器节点间的沟通联络采用的是远程过程调用(RPC),在领导者选举中,需要用到这两类的RPC:

  • 请求投票(RequestVote)RPC:是由候选人在选举期间发起,通知各节点进行投票
  • 日志复制(AppendEntries)RPC:是由领导者发起,用来复制日志和提供心跳消息

4)、什么是任期?

Raft算法中每个任期由单调递增的数字(任期编号)标识,任期编号是随着选举的举行而变化的

  1. 跟随者在等待领导者心跳信息超时后,推举自己为候选人时,会增加自己的任期编号,比如节点A的任期编号为0,那么在推举自己为候选人时,会将自己的任期编号增加为1
  2. 如果一个服务器节点,发现自己的任期编号比其他节点小,那么它会更新自己的任期编号到较大的编号值,比如节点B的任期编号是0,当收到来自节点A的请求投票RPC消息时,因为消息中包含了节点A的任期编号,且编号为1,那么节点B将把自己的任期编号更新为1
  3. 如果一个候选人或者领导者,发现自己的任期编号比其他节点小,那么它会立即恢复成跟随者状态。比如分区错误恢复后,任期编号为3的领导者节点B,收到来自新领导者的包含任期编号为4的心跳消息,那么节点B将立即恢复成跟随者状态
  4. 如果一个节点接收到一个包含较小的任期编号值的请求,那么它会直接拒绝这个请求。比如节点C的任期编号为4,收到包含任期编号为3的请求投票RPC消息,那么它将拒绝这个消息

5)、选举有哪些规则?

  1. 领导者周期性地向所有跟随者发送心跳消息(即不包含日志项的日志复制RPC消息),通知大家我是领导者,组织跟随者发起新的选举

  2. 如果在指定时间内,跟随者没有接收到来自领导者的消息,那么它就认为当前没有领导者,推举自己为候选人,发起领导者选举

  3. 在一次选举中,赢得大多数选票的候选人,将晋升为领导者

  4. 在一个任期内,领导者一直都会是领导者,直到它自身出现问题(比如宕机),或者因为网络延迟,其他节点发起一轮新的选举

  5. 在一次选举中,每一个服务器节点最多会对一个任期编号投出一张选票,并且按照先来先服务的原则进行投票。比如节点C的任期编号为3,先收到了一个包含任期编号为4的投票请求(来自节点A),然后又收到了一个包含任期编号为4的投票请求(来自节点B)。那么节点C将会把唯一一张选票投给节点A,当再收到节点B的投票请求RPC消息时,对于编号为4的任期,已没有选票可投了

watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQwMzc4MDM0,size_16,color_FFFFFF,t_70#pic_center

  1. 日志完整性高的跟随者(也就是最后一条日志项对应的任期编号值更大,索引号更大)拒绝投票给日志完整性低的候选人。比如节点B的任期编号为3,节点C的任期编号为4,节点B的最后一条日志项对应的任期编号为3,而节点C为2,那么当节点C请求节点B投票给自己时,节点B将拒绝投票

在这里插入图片描述

选举是跟随者发起的,推举自己为候选人;大多数选票是指集群成员半数以上的选票;大多数选票规则的目标,是为了保证在一个给定的任期内最多只有一个领导者

6)、随机超时时间是什么?

Raft算法使用随机选举超时时间的方法,把超时时间都分散开来,在大多数情况下只有一个服务器节点先发起选举,而不是同时发起选举,这样就能减少因选票瓜分导致选举失败的情况

在Raft算法中,随机超时时间有2种含义:

  1. 跟随者等待领导者心跳信息超时的时间间隔是随机的
  2. 如果候选人在一个随机时间间隔内,没有赢得过半票数,那么选举就无效了,然后候选人发起新一轮的选举,也就是说,等待选举超时的时间间隔是随机的

7)、补充

1)Raft算法的强领导者模型选举限制和局限如下:

  1. 读写请求和数据转发压力落在领导者节点,相当于单机,性能和吞吐量也会受到限制
  2. 大规模跟随者的集群,领导者需要承担大量元数据维护和心跳通知的成本
  3. 领导者单点问题,故障后直到新领导者选举出来期间集群不可用
  4. 随着候选人规模增长,收集半数以上投票的成本更大

2)强领导者模型会限制集群的写性能,有什么办法能突破Raft集群的写性能瓶颈呢?

参考Kafka的分区和ES的主分片副本分片这种机制,虽然写入只能通过Leader写,但每个Leader可以负责不同的片区,来提高写入的性能

2、日志复制

1)、如何理解日志?

副本数据是以日志的形式存在的,日志是由日志项组成,日志项是一种数据格式,它主要包含用户指定的数据,也就是指令(Command),还包含一些附加信息,比如索引值(Log index)、任期编号(Term)

watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQwMzc4MDM0,size_16,color_FFFFFF,t_70#pic_center

  • 指令:一条由客户端请求指定的、状态机需要执行的指令,可以理解成客户端指定的数据
  • 索引值:日志项对应的整数索引值,用来标识日志项的,是一个连续的、单调递增的证书号码
  • 任期编号:创建这条日志项的领导者的任期编号

2)、如何复制日志?

首先,领导者通过日志复制(AppendEntries)RPC消息,将日志项复制到集群其他节点上

接着,如果领导者接收到大多数的复制成功响应后,它将日志项应用到它的状态机,并返回成功给客户端。如果领导者没有接收到大多数的复制成功响应,那么就返回错误给客户端

领导者将日志项应用到它的状态机,怎么没通知跟随者应用日志项呢?

因为领导者的日志复制RPC消息或心跳消息,包含了当前最大的、将会被提交的日志项索引值。所以通过日志复制RPC消息或心跳消息,跟随者就可以知道领导者的日志提交位置信息

watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQwMzc4MDM0,size_16,color_FFFFFF,t_70#pic_center

  1. 接收到客户端请求后,领导者基于客户端请求中的指令,创建一个新日志项,并附加到本地日志中
  2. 领导者通过日志复制RPC,将新的日志复制到其他的服务器
  3. 当领导者将日志项成功复制到大多数的服务器上的时候,领导者会将这条日志项应用到它的状态机中
  4. 领导者将执行的结果返回给客户端
  5. 当跟随者接收到心跳消息,或者新的日志复制RPC消息后,如果跟随者发现领导者已经提交了某条日志项,而它还没应用,那么跟随者就将这条日志项应用到本地的状态机上

3)、如何实现日志的一致?

在Raft算法中,领导者通过强制跟随者直接复制自己的日志项,处理不一致日志。也就是说,Raft是通过以领导者的日志为准,来实现各节点日志的一致性的

  1. 首先,领导者通过日志复制RPC的一致性检查,找到跟随者节点上与自己相同日志项的最大索引值。也就是说,这个索引值之前的日志,领导者和跟随者是一致的,之后的日志是不一致的
  2. 然后,领导者强制跟随者更新覆盖不一致的日志项,实现日志的一致

引入2个新变量:

  • PrevLogEntry:表示当前要复制的日志项,前面一条日志项的索引值。比如下图中,如果领导者将索引值为8的日志项发送给跟随者,那么此时PrevLogEntry值为7
  • PrevLogTerm:表示当前要复制的日志项,前面一条日志项的任期编号,比如在图中,如果领导者将索引值为8的日志项发送给跟随者,那么此时PrevLogTerm值为4

watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQwMzc4MDM0,size_16,color_FFFFFF,t_70#pic_center

  1. 领导者通过日志复制RPC消息,发送当前最新日志项到跟随者,这个消息的PrevLogEntry值为7、PrevLogTerm值为4
  2. 如果跟随者在它的日志中,找不到PrevLogEntry值为7、PrevLogTerm值为4的日志项,也就是说它的日志和领导者的不一致了,那么跟随者就会拒绝接收新的日志项,并返回失败消息给领导者
  3. 这时,领导者会递减要复制的日志项的索引值,并发送新的日志项到跟随者,这个消息的PrevLogEntry值为6、PrevLogTerm值为3
  4. 如果跟随者在它的日志中,找到了PrevLogEntry值为6、PrevLogTerm值为3的日志项,那么日志复制RPC返回成功,这样一来,领导者就知道在PrevLogEntry值为6、PrevLogTerm值为3的位置,跟随者的日志项与自己相同
  5. 领导者通过日志复制RPC复制并更新覆盖该索引值之后的日志项(也就是不一致的日志项),最终实现了集群各节点日志的一致

领导者通过日志复制RPC一致性检查,找到跟随者节点上与自己相同日志项的最大索引值,然后复制并更新覆盖该索引值之后的日志项,实现了各节点日志的一致。跟随者中的不一致日志项会被领导者的日志覆盖,而且领导者从来不会覆盖或者删除自己的日志

4)、补充

1)领导者接收到大多数的“复制成功”响应后,就会将日志应用到它自己的状态机,然后返回“成功”响应客户端。如果此时有个节点不在“大多数”中,也就是说它接收日志项失败,那么在这种情况下,Raft会如何处理实现日志的一致呢?

处理日志项一致通过RPC一致性检查,找到跟随者中与自己相同日志项的最大索引,然后把后面的日志项同步过去,让跟随者复制更新

2)Raft在处理日志不一致时会给跟随者发送RPC一致性检查,找到和自己相同日志项的最大值,这里是对每个跟随者而言的还是所有的跟随者而言的?

日志复制信息对每个跟随者都要单独维护的

参考:

07 | Raft算法(一):如何选举领导者?

08 | Raft算法(二):如何复制日志?


---------------------
作者:邋遢的流浪剑客
来源:CSDN
原文:https://blog.csdn.net/qq_40378034/article/details/117404484
版权声明:本文为作者原创文章,转载请附上博文链接!
内容解析By:CSDN,CNBLOG博客文章一键转载插件

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

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

相关文章

淘宝弹性布局方案lib-flexible研究

1. lib-flexible不能与响应式布局兼容 先说说响应式布局的一些基本认识: 响应式布局的表现是:网页通过css媒介查询判断可视区域的宽度,在不同的范围应用不同的样式,以便在不同尺寸的设备上呈现最佳的界面效果。典型的例子是&#…

WPF效果第一百九十四篇之伸缩面板

前面一篇玩耍了一下登录实现效果;今天在原来的基础上来玩耍一下伸缩面板的效果;闲话不多扯直接看效果:1、关于前台简单布局:2、左侧面板伸缩动画&#xff1a;<Storyboard x:Key"ShowConfigSb"><ThicknessAnimationUsingKeyFrames Storyboard.TargetProperty…

【.NET 6】开发minimal api以及依赖注入的实现和代码演示

前言&#xff1a;.net 6 LTS版本发布已经有一段时间了。此处做一个关于使用.net 6 开发精简版webapi&#xff08;minimal api&#xff09;的入门教程演示。1、新建一个项目。此处就命名为 SomeExample:2、选择 .net6版本&#xff0c;并且此处先去掉HTTPS配置以及去掉使用控制器…

(转载)VS2010/MFC编程入门之四(MFC应用程序框架分析)

上一讲鸡啄米讲的是VS2010应用程序工程中文件的组成结构&#xff0c;可能大家对工程的运行原理还是很模糊&#xff0c;理不出头绪&#xff0c;毕竟跟C编程入门系列中的例程差别太大。这一节鸡啄米就为大家分析下MFC应用程序框架的运行流程。 一.SDK应用程序与MFC应用程序运行过…

2022年中国中小学教育信息化行业研究报告

教育信息化丨研究报告 核心摘要&#xff1a; 背景篇 目前&#xff0c;我国中小学教育主要呈现信息时代教育的特征&#xff0c;智能时代教育特征初露端倪&#xff1b;中小学教育信息化正从量变迈向质变&#xff0c;创新引领与生态变革成为行业纵深的主旋律&#xff1b; 2021年…

使用curl指令发起websocket请求

昨日的文章没指出websocket请求协商切换的精髓&#xff0c;删除重发。前文相关&#xff1a;• .NET WebSockets 核心原理初体验[1]• SignalR 从开发到生产部署避坑指南[2]tag&#xff1a;浏览器--->nginx--> server其中提到nginx默认不会为客户端转发Upgrade、Connectio…

Yii 2 的安装 之 踩坑历程

由于刚接触yii2 ,决定先装个试试&#xff1b;可是这一路安装差点整吐血&#xff0c;可能还是水平有限吧&#xff0c; 但还是想把这个过程分享出来&#xff0c;让遇到同样问题的同学有个小小的参考&#xff0c;好了言归正传&#xff01;&#xff01; <(~.~)> 下面是安装流…

设计模式之代理模式(上) 静态代理与JDK动态代理

2019独角兽企业重金招聘Python工程师标准>>> 代理模式 给某一个对象提供一个代理&#xff0c;并由代理对象控制对原对象的引用。静态代理 静态代理是由我们编写好的类&#xff0c;在程序运行之前就已经编译好的的类&#xff0c;此时就叫静态代理。 说理论还是比较懵…

WPF 实现更换主题色

WPF 实现更换主题色WPF 使用 WPFDevelopers.Minimal 如何更换主题色作者&#xff1a;WPFDevelopersOrg原文链接&#xff1a; https://github.com/WPFDevelopersOrg/WPFDevelopers.Minimal框架使用大于等于.NET40&#xff1b;Visual Studio 2022;项目使用 MIT 开源许可协议&a…

vue3与vue2的区别

先来说说当下市场开发使用的问题&#xff0c;目前2021年使用vue3开发的企业还是少&#xff0c;基本上都还是以vue2的形式进行开发&#xff0c;vue3的开发模式跟react很像&#xff0c;这时候有人就会想那我学vue3有用么&#xff0c;淦&#xff0c;他喵的&#xff0c;先别激动&am…

Spring Data REST API集成Springfox、Swagger

原文: Documenting a Spring Data REST API with Springfox and Swagger 使用Spring Date REST&#xff0c;你可以迅速为Spring Date repositories的创建REST API&#xff0c;并提供CRUD和更多功能。然而&#xff0c;在严谨的API开发过成功&#xff0c;您还希望拥有自动生成的最…

【系统设计】S3 对象存储

在本文中&#xff0c;我们设计了一个类似于 Amazon Simple Storage Service (S3) 的对象存储服务。S3 是 Amazon Web Services (AWS) 提供的一项服务&#xff0c; 它通过基于 RESTful API 的接口提供对象存储。根据亚马逊的报告&#xff0c;到 2021 年&#xff0c;有超过 100 万…

转: telnet命令学习

1.每天一个linux命令&#xff08;58&#xff09;&#xff1a;telnet命令 转自&#xff1a; http://www.cnblogs.com/peida/archive/2013/03/13/2956992.html telnet命令通常用来远程登录。telnet程序是基于TELNET协议的远程登录客户端程序。Telnet协议是TCP/IP协议族中的一员&a…

禅道、码云、coding、redmine、jira、teambition几大敏捷开发项目管理系统试用对比体验

作为一个软件公司的管理人员&#xff0c;在项目和人员多起来后&#xff0c;就需要通过系统来对项目和人员进行管理。 我们是典型的软件外包公司&#xff0c;专为客户定制软件&#xff0c;所以我们的业务都是项目型的。因此&#xff0c;在管理模式上&#xff0c;我们就要用所谓…

Dubbo中的SPI机制

Dubbo中的SPI机制 概述 Service Provider Interface 即 SPI&#xff0c;是JDK内置的一种服务提供发现机制&#xff0c;可以用来启用框架扩展和替换组件。可以让不同的厂商针对统一接口编写不同的实现 SPI实际上是“接口策略模式配置文件”实现的动态加载机制。在系统设计中&…

JWT:拥有我,即拥有权力

Hi&#xff0c;这里是桑小榆。上篇文章中&#xff0c;我们一起探讨了 OAuth 协议的原理以及授权认证流程&#xff0c;本次我们一起探讨 jwt 令牌作为授权协议的传输介质。OAuth协议规范了几个参与角色的授权标准&#xff0c;安全可控的授予第三方应用&#xff0c;第三方应用获取…

双十一到来之前,阿里AI设计师“鲁班”1天能做4000万张海报

相比较去年&#xff0c;“鲁班”的设计技艺有所提升。 人工智能很大程度上便利了我们的生活&#xff0c;现在他们甚至还能取代了一些设计师的工作&#xff0c;在双十一正式到来之前&#xff0c;淘宝的宣传已经铺天盖地&#xff0c;然而很多人都没想到&#xff0c;我们打开淘宝…

Appium移动自动化测试之获取appPackage和appActivity

方法一&#xff1a;直接打开Appium,点击左上角机器人图标 选择apk所在位置&#xff0c;如图所示&#xff0c;这里以ContactManager.apk为例 方法二&#xff1a;利用dex2jar和jd-gui这两个工具反编译apk文件 这里仍以ContactManager.apk为例 (1)重命名ContactManager.apk为Conta…

CAD转WPF: 关于CAD图纸文件转换为WPF矢量代码文件(xaml文件)的技巧

前言&#xff1a;下面的文章&#xff0c;我将会以几个很简单的步骤&#xff0c;来演示一下通过CAD图纸转换为XAML代码文件的方法&#xff0c;供大佬们参考。一、为了演示一个简单的操作&#xff0c;我此处先打开一个空白的CAD&#xff0c;等下用来进行绘制点内容使用。二、自定…

python之新式类与经典类

经典类与新式类经典类:P 或 P()--深度查找&#xff0c;向上查父节点新式类 :P(object)---广度查找&#xff0c;继承object&#xff0c;新式类的方法较多转载于:https://www.cnblogs.com/zyy98877/p/8574983.html