分布式之raft一致性算法

news2024/11/17 11:54:39

1.CAP定理

在一个分布式系统中,CAP三者不可兼得,最多只有两者可以满足正所谓鱼和熊掌不可兼得

  • 一致性 Consistency:所有的节点在同一时间的数据一致
  • 可用性 Availability:服务在正常响应时间内可用
  • 分区容错性 Partition-tolerance:分区故障仍能对外提供一致性或可用性服务。

1.1 一致性问题的是由于分区(多台服务器),因为当服务器多了以后,要遵循一致性就比较麻烦。

1.2 数据冗余可以提供系统的可用性和分区容错性,但是难以满足强一致性,数据冗余指的就是

把数据副本打散在各个分区,但是这并不能满足强一致性是因为:

假设有一个分布式系统,其中有两个节点 A 和 B,它们存储相同的数据副本。考虑下面的场景:

  1. 客户端向节点 A 发送一个写请求,要求将某个数据从 X 修改为 Y。
  2. 节点 A 接收到写请求后,将数据从 X 修改为 Y,并响应客户端写操作成功。
  3. 同时,客户端向节点 B 发送一个读请求,希望获取最新的数据。
  4. 由于数据冗余,节点 B 的数据也应该是最新的。然而,在分布式系统中,节点之间可能存在通信延迟或网络分区等问题,导致数据同步需要一些时间。

若要解决一致性问题,达到强一致性,需要把所有请求全部通过单台服务器处理,很难达到可用性。

因此,对于分布式系统,需要在一致性、可用性和分区容错性间中取舍。从经验上看,可用性或一致性往往是被弱化的对象。

对于高可用的系统来说,往往保留强一致性。因此,计算机界通过共识算法来解决此类问题。

共识算法保证所有的参与者都有相同的认知,即强一致性。常见的共识算法有:

  • paxos 算法:代表 Zookeeper
  • Raft 算法:代表 Etcd

本文主要介绍 Raft 一致性算法。流程演示可参考:Raft 算法流程

2. Raft 基本概念


Raft 算法是主从模型(单 Leader 多 Follower)。所有的请求全部由 Leader 处理。Leader 处理请求时,先追加一条日志,然后把日志同步给 Follower。当写入成功的节点过半后持久化日志,

Raft 节点有三种角色

  • Leader(主副本)
  • Candidate (候选副本)
  • Follower (副副本)

Raft 投票机制

  • 节点不能重复投票。Follower 节点记录自己投过的节点,在一个任期内不会重复投票
  • 一节点一票。Candidate 节点投给自己,Follower 节点投给向自己拉票的 Candidate

Raft 节点间使用的消息有两种

  • RequesetVote:请求其他节点给自己投票,由 Candidate 节点发出
  • AppendEntries:附加条目,条目数量 > 0,日志复制;条目数量 > 0 = 0,心跳信息,由 Leader 节点发出

任期 Term:逻辑时钟值,全局递增,描述一个 Leader 的任期

3、Raft 算法核心

Raft 算法核心是

  • Leader 选举
  • 日志复制

3.1、Leader 选举

Leader 选举流程

集群中的节点刚启动时,所有节点都是 Follower 节点。
当 Leader 发送的心跳超时,Follower 节点自动变成 Candidate 节点,自荐成为选举候选人,并向其他节点发送 RequesetVote 消息
若 Candidate 节点收到过半支持 (n+1)/2 后,变成 Leader 节点。新的 Leader 节点立即向其他节点发送心跳消息 AppendEntries,其他节点重置自己的选举超时时间,并保持 Follower 角色。
当集群节点数是偶数,可能会出现平票的情况,如图所示,两个 Candidate 节点分别得到 2 票,票数均未过半,无法选出 Leader 节点,该现象被称为分割选举 split vote。进入下一轮选举。

为了避免分割选举的现象出现,Raft 算法使用随机选举超时来降低 split vote 出现的概率。这样每个节点成为 Candidate 节点的时间点被错开了,提高了 Leader 节点选举成功的概率。

在选出 Leader 节点后,各个节点需要在最短时间内获取新的 Leader 节点信息,否则选举超时又会进入新一轮选举。因此心跳超时 << 选举超时。

节点的选举时间在收到心跳消息后会重置。如果不重置,节点会频繁发起选举。这样避免了节点频繁发起选举,系统收敛于稳定状态。只要 Leader 持续不断发送心跳信息,Follower 节点就不会成为 Candidate 角色并发起选举。

至此,选举结束,Leader 节点和 Follower 节点间开始日志同步。

任何导致心跳超时的事件,例如:集群启动、Leader 节点宕机、网络分区等,都会导致集群 Leader 选举。
 

Leader 选举控制

  • 心跳超时:Follower 节点在规定时间内没有收到 leader 的心跳消息。
  • 选举超时:随机值,Follower 等待变成 Candidate 的时间。定时器到期,Follower 节点自动成为 Candidate 节点,将选举任期 + 1。

可以这样理解:
Leader 节点是君主,Follower 节点是有野心的臣子,蠢蠢欲动,随时密谋造反。只要 Leader 定期发号施令(心跳消息),Follower 收到心跳消息后,忌惮君主实力,不敢造反(重置选举超时)。
倘若一段时间后 Follower 不再收到君主的消息(心跳超时),Follower 准备妥当后(选举超时)成为 Candidate。自立为王,并胁迫其他 Follower 支持自己(RequesetVote 消息)。一旦获得半数以上的 Follower 支持,新王加冕。
新的 Leader 立刻发送心跳消息,迫使其他 Candidate 放弃造反,继续保持 Follower 身份。
 

 

3.2、日志复制


Raft 算法中,所有来自客户端的数据变更请求都会被当作一个日志条目追加到节点日志中。

日志条目有以下两种状态:

已追加,但是尚未提交(没有持久化)
已提交(持久化)
Raft 算法中的节点维护已提交日志条目索引 commitIndex,小于等于该值的日志条目被认为是已提交,否则就是尚未持久化的数据。
 

 

Raft 日志复制流程

日志追加
日志提交
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-czAthxE1-1678935556629)(云原生.assets/Raft_日志复制.png)]

客户端向 Leader 发送数据变更请求,Leader 节点向自己的日志中追加一条日志,接下来通过 AppendEntries 消息向其他节点同步数据。当超过半数节点(包括 Leader 自己)追加新日志成功后,Leader 节点持久化日志并提交日志,然后再次通过 AppendEntries 消息通知其他节点持久化日志。

一般情况,日志复制需要来回发送两次 AppendEntries 消息(追加日志和提交日志)。需要发送两次的主要原因是需要确保过半追加成功后,系统才能正常提交日志。假设不确认过半追加,当碰到脑裂或者网络分区时,会出现数据严重不一致的问题。

例如:如图所示,Raft 集群中,原 Leader 是 B 节点,其他都是 Follower,任期是 1。在某一时刻出现网络分区,节点 A、B 处在同一分区,A 仍可以接受 B 的心跳信息,保持 Follower。节点 C、D、E 无法收到 B 的心跳消息,选举超时后,选举 C 作为新的 Leader 节点,任期 + 1。
 

 

当客户端连接节点 B 和 C 分别写入,对于分区 A,B,追加日志后,没有收到半数以上节点的确认(2 个节点),无法提交日志;对于分区 C,D,E,追加日志后,收到半数以上节点的确认(3 个节点),提交日志成功。此时,Leader B 和 Leader C 日志冲突。

当网络分区恢复后,Leader B 节点发现 Leader C 节点的任期 Term 的值更高, 降级为 Follower。则节点 A 和 B 丢弃自己的日志,同步 Leader C 的日志消息。此时,日志保持一致。

4、总结


Raft 的读写

所有来自客户端的读写请求,全部由 Leader 节点处理。

Raft 节点的三种状态

Follower:随机选举超时,自动成为 Candidate
Candidate:主动给自己投票,向其他节点广播拉票,当自身选票超过半数以上成为 Leader
Leader:定时向其他节点发送心跳消息,并同步变化信息;若 Leader 发现有比自身更高的任期,则自己立刻下台成为 Follower,并接受新的 Leader 的数据变更同步
Raft 节点的状态变化

Follower -> Candidate:选举超时,自动成为 Candidate
Candidate -> Candidate:本轮选举,开启新一轮选举
Candidate -> Leader:获得半数以上节点的支持
Leader -> Follower:发现更高的任期
Candidate -> Follower:收到 Leader 的心跳消息
 

Follower 处理其他节点发送来的消息

candidate:向第一次接收到的拉票所属 candidate 发送投票,并将自己的任期设置为该 candidate 的任期。同时会重置自身选举超时和心跳超时
Leader:重置自身选举超时和心跳超时


平票后,下一轮选举

选举任期 Term + 1
重新随机一个选举超时
重置上轮的选票


日志复制流程

日志追加:收到数据变更请求,Leader 将追加日志到本地,向其他节点同步数据,待半数以上节点追加成功后,开始日志持久化。
日志提交:Leader 将本地日志持久化,并通知其他节点日志持久化。


Raft 修复脑裂后,如何恢复一致性

发生脑裂:无法接收到心跳消息的分区重新选举新的 Leader 节点,分区内所有节点任期 + 1
修复脑裂:若 Leader 节点发现集群中有比自己任期还高的 Leader 节点, 则降级为 Follower,接收 Leader 的数据同步
 

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

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

相关文章

〖大前端 - 基础入门三大核心之JS篇(51)〗- 面向对象之认识上下文与上下文规则

说明&#xff1a;该文属于 大前端全栈架构白宝书专栏&#xff0c;目前阶段免费&#xff0c;如需要项目实战或者是体系化资源&#xff0c;文末名片加V&#xff01;作者&#xff1a;哈哥撩编程&#xff0c;十余年工作经验, 从事过全栈研发、产品经理等工作&#xff0c;目前在公司…

UnoCSS 原子化开发初体验

UnoCSS 是一个即时的原子化 CSS 引擎&#xff0c;旨在灵活和可扩展。核心是不拘一格的&#xff0c;所有的 CSS 工具类都是通过预设提供的。再也不用为了取一个 classname 类名而烦恼了。 一、UnoCSS 特点 完全可定制&#xff1a;无核心工具&#xff0c;所有功能都通过预设提供…

DevEco Studio IDE 创建项目时候配置环境

DevEco Studio IDE 创建项目时候配置环境 一、安装环境 操作系统: Windows 10 专业版 IDE:DevEco Studio 3.1 SDK:HarmonyOS 3.1 二、在配置向导的时候意外关闭配置界面该如何二次配置IDE环境。 打开IDE的界面是这样的。 点击Create Project进行环境配置。 点击OK后出现如…

(企业 / 公司项目) 企业项目如何使用jwt?

按照企业的项目然后写的小demo&#xff0c; 自己搞一个登录接口然后调用jwtUtil工具类 后端实现 创建一个通用模块common来实现jwt生成token 登录注册的基本实现逻辑思路 面试| ProcessOn免费在线作图,在线流程图,在线思维导图 注释挺详细的jwtUtil工具类&#xff0c; 封装的…

基于OpenCV+CNN+IOT+微信小程序智能果实采摘指导系统——深度学习算法应用(含python、JS工程源码)+数据集+模型(五)

目录 前言总体设计系统整体结构图系统流程图 运行环境Python环境TensorFlow 环境Jupyter Notebook环境Pycharm 环境微信开发者工具OneNET云平台 模块实现1. 数据预处理2. 创建模型并编译3. 模型训练及保存4. 上传结果5. 小程序开发1&#xff09;查询图片2&#xff09;查询识别结…

文献速递:多模态影像组学文献分享多模态放射组学预测直肠癌患者放疗引发的早期直肠炎和膀胱炎:一项机器学习研究

文献速递&#xff1a;多模态影像组学文献分享:多模态放射组学预测直肠癌患者放疗引发的早期直肠炎和膀胱炎&#xff1a;一项机器学习研究 01 文献速递介绍 Rectal cancer is the second most prevalent form of cancer in the large intestine, and its primary treatment …

Android---Kotlin 学习002

声明变量 在 Kotlin 中定义一个变量&#xff0c;通过关键字 var 开始。然后是变量名&#xff0c;在“:”后紧跟变量类型。 示例1&#xff1a;声明一个 int 类型的变量 var num:Int 1 示例2&#xff1a;声明一个 String 类型的变量 var str:String "Hello world&quo…

C# OpenCvSharp DNN 部署FastestDet

目录 效果 模型信息 项目 代码 下载 C# OpenCvSharp DNN 部署FastestDet 效果 模型信息 Inputs ------------------------- name&#xff1a;input.1 tensor&#xff1a;Float[1, 3, 512, 512] --------------------------------------------------------------- Outpu…

QT----第二天QMainWindow,各种控件

目录 第二天1 QMainWindow1.1 菜单栏1.2工具栏1.3 状态栏1.4 铆接&#xff08;浮动窗口&#xff09;和中心部件&#xff08;只能由一个&#xff09;2 资源文件添加 3、对话框Qdialog3.2 模态和非模态对话框3.2 消息对话框3.3 其他对话框 4 登陆界面5 按钮组控件5.1QToolButton5…

机器学习中的 Transformation Pipelines(Machine Learning 研习之十)

Transformation Pipelines 有许多数据转换步骤需要以正确的顺序执行。幸运的是&#xff0c;Scikit-Learn提供了Pipeline类来帮助处理这样的转换序列。下面是一个用于数值属性的小管道&#xff0c;它首先对输入特性进行归并&#xff0c;然后对输入特性进行缩放: from sklearn.…

Nginx访问FTP服务器文件的时效性/安全校验

背景 FTP文件服务器在我们日常开发中经常使用&#xff0c;在项目中我们经常把FTP文件下载到内存中&#xff0c;然后转为base64给前端进行展示。如果excel中也需要导出图片&#xff0c;数据量大的情况下会直接返回一个后端的开放接口地址&#xff0c;然后在项目中对接口的参数进…

微信小程序 ios 手机底部安全区适配

在开发微信小程序中&#xff0c;遇到 IOS 全面屏手机&#xff0c;底部小黑条会遮挡页面按钮或内容&#xff0c;因此需要做适配处理。 解决方案 通过 wx.getSystemInfo() 获取手机系统信息&#xff0c;需要拿到&#xff1a;screenHeight&#xff08;屏幕高度&#xff09;&#…

持续集成交付CICD:GitLabCI上传Nexus制品

目录 一、实验 1.GitLabCI上传Nexus制品 2.优化GitLabCI&#xff08;引用系统变量&#xff09; 3.添加if条件判断项目类型 4.优化GitLabCI&#xff08;模板类&#xff09; 二、问题 1.GitLabCI获取jar文件失败 2. GitLabCI获取流水线项目命名空间失败 3.GItLab Packag…

学习pytorch19 pytorch使用GPU训练2

pytorch使用GPU训练2 第二种使用gpu方式核心代码代码 macbook pro m1/m2 用mps &#xff0c; 是苹果arm芯片的gpu 第二种使用gpu方式核心代码 # 设置设备 device torch.device(cpu) # 使用cpu device torch.device(cuda) # 单台gpu device torch.device(cuda:0) # 使…

基于大语言模型的复杂任务认知推理算法CogTree

近日&#xff0c;阿里云人工智能平台PAI与华东师范大学张伟教授团队合作在自然语言处理顶级会议EMNLP2023上发表了基于认知理论所衍生的CogTree认知树生成式语言模型。通过两个系统&#xff1a;直觉系统和反思系统来模仿人类产生认知的过程。直觉系统负责产生原始问题的多个分解…

打包CSS

接上一个打包HTML继续进行CSS的打包 1.在之前的文件夹里的src文件夹创建一个css文件 2.在浏览器打开webpack——>中文文档——>指南——>管理资源——>加载CSS 3.复制第一句代码到终端 4.复制下图代码到webpack.config.js脚本的plugins&#xff1a;[.....]内容下…

计算机循环神经网络(RNN)

计算机循环神经网络&#xff08;RNN&#xff09; 一、引言 循环神经网络&#xff08;RNN&#xff09;是一种常见的深度学习模型&#xff0c;适用于处理序列数据&#xff0c;如文本、语音、时间序列等。RNN通过捕捉序列数据中的时间依赖关系和上下文信息&#xff0c;能够解决很…

网络编程_网络编程三要素,TCP协议,UDP协议

网络编程 文章目录 网络编程1 网络编程三要素1.1 IP地址1.1.1 IP地址分为两大类1.1.2 DOS常用命令1.1.3 特殊IP地址 1.2 InetAddress类_表示IP地址的类1.2.1 相关方法1.2.2 示例 1.3 端口和协议1.3.1 端口与端口号1.3.2 协议1.3.3 UDP协议1.3.4 TCP协议 2 UDP通信程序2.1 UDP发…

Leetcode 1631. 最小体力消耗路径

一、题目 1、题目描述 你准备参加一场远足活动。给你一个二维 rows x columns 的地图 heights &#xff0c;其中 heights[row][col] 表示格子 (row, col) 的高度。一开始你在最左上角的格子 (0, 0) &#xff0c;且你希望去最右下角的格子 (rows-1, columns-1) &#xff08;注意…

启动cad显示丢失mfc140u.dll怎么办?mfc140u.dll丢失有效解决方法分享

在CAD软件或其他软件中&#xff0c;有时候会出现由于找不到mfc140u.dll文件而无法执行代码的错误提示。这个问题可能是由于多种原因引起的&#xff0c;例如文件损坏、缺失或被病毒感染等。下面将介绍五个常见的解决方法&#xff0c;并解释mfc140u.dll丢失的原因以及该文件对CAD…