【分布式】分布式共识算法 --- RAFT

news2024/11/18 9:44:25

2.CAP原则

CAP原则又称CAP定理,指的是在一个分布式系统中,一致性(Consistency)、可用性(Availability)、分区容错性(Partition tolerance)

It states, that though its desirable to have Consistency, High-Availability and Partition-tolerance in every system, unfortunately no system can achieve all three at the same time.
在分布式系统的设计中,没有一种设计可以同时满足一致性,可用性,分区容错性 3个特性

1998年,加州大学的计算机科学家 Eric Brewer 提出,分布式系统有三个指标。

  1. 一致性(C):在分布式系统中的所有数据备份,在同一时刻是否同样的值,即写操作之后的读操作,必须返回该值。(分为弱一致性、强一致性和最终一致性)
  2. 可用性(A):在集群中一部分节点故障后,集群整体是否还能响应客户端的读写请求。(对数据更新具备高可用性)
  3. 分区容忍性(P):以实际效果而言,分区相当于对通信的时限要求。系统如果不能在时限内达成数据一致性,就意味着发生了分区的情况,必须就当前操作在C和A之间做出选择

要满足CAP理论,而分布式共识算法解决的就是CAP理论中的一致性问题。整个一致性问题分为三种问题:

  1. 顺序一致性
  2. 线性一致性
  3. 因果一致性

其中线性一致性要求所有线程的操作按照一个绝对的时钟顺序执行,这意味着线性一致性是限制并发的,否则这种顺序性就无法保证。由于在真实环境中很难保证绝对时钟同步,因此线性一致性是一种理论。

实现线性一致性的代价也最高,但是实战中可以弱化部分线性一致性:只保证有因果关系的事件的顺序,没有因果关系的事件可以并发执行,其指的是假设有两个事件:A事件和B事件,如果A发生在B后面,那么就称A和B具有因果关系。

Paxos和Raft这些分布式共识算法就是用来多个节点之间达成共识的,其可以解决一定的一致性问题。其中raft对于分布式的入门者来说最好理解,因此,我们选择raft作为我们的讲解目标。


2. 共识算法RAFT

2.1 数据处理流程

在这里插入图片描述
在深入了解raft的实现之前,我们需要先对拥有raft的分布式集群有一个宏观了解。

当我们向集群中的每一台主机中加入一致性协议之后,我们数据的存储会发生什么变化?

根据上图我们可以大致推断:

  1. 客户端发出命令,被集群中的一台机器接收,不直接提交到状态机(State Machine)进行持久化,而是先提交到 共识协议层(Consensus Moudle)
  2. 共识协议层(Consensus Moudle)将客户端命令持久化到本地日志中,同时分发到其他机器上
  3. 当其他机器会收到含有命令的日志,并持久化,最后从日志中取出命令,应用到状态机

2.2 RAFT 详解

2.2.1 RAFT 状态机

遵循Raft算法的分布式集群中每个节点扮演以下三种角色之一:

leader:领导者,其负责和客户端通信,接收来自客户端的命令并将其转发给follower

follower:跟随者,其一丝不苟的执行来自leader的命令

candidate:候选者,当follower长时间没收到 leader的消息就会揭竿而起成为候选者,抢夺成为leader的资格
在这里插入图片描述

2.2.2 节点数据结构定义

在这里插入图片描述

其中各个字段分为需要持久化的与不需要持久化的(易失的):

持久化状态

参数解释
currentTerm服务器最新任期,可理解为逻辑时钟
voteFor当前term内自己给候选人投票的候选人Id,未投票则为-1
log[]日志条目,单条日志包括 客户端操作,leader接收到该条目时的term,以及日志索引(初始为1,如图)

currentTerm 参数raft集群内的逻辑时钟值,全局递增,准确来说时Lamport Timestamp的变体。

Lamport Timestamp算法
该算法十分简单,当一个集群内的多台机器需要维护一个全局时间,可以这样做:

  1. 每个进程本地存储一份全局时间副本
  2. 某进程内时间发送,递增自身时间副本
  3. 发送消息时附加上时间副本值
  4. 收到消息,比较消息中与自己的时间副本值,选择较大的时间值加1,并更新自身时间

易失性状态

参数解释初始值
commitIndex已知提交的最高的日志条目的索引0
lastApplied已知被应用到状态机的最高的日志条目的索引0

除此之外,Leader还维护了两个数组:

Leader易失性状态

参数解释初始值
nextIdx []对于i号节点,发送到该节点的下一跳日志的索引Leader最后日志条目索引+1
matchIdx[]对于i号节点,已知的已经复制到该节点的最高日志条目的索引0,单调递增

2.2.3 节点 RPC 操作

2.2.3.1 请求投票(RequestVote)

候选人发起选举投票RPC到集群内的其他节点

  • 请求参数 (RequestVoteArgs)
参数解释
term候选人任期号
candidateId候选人Id
lastLogIndex候选人最后的日志条目的索引
lastLogTerm候选人最后日志条目的term
  • 响应参数 (RequestVoteReply)
参数解释
term当前任期号,帮助候选者更新自身任期号
voteGranded候选人是否赢得此张选票
  • 选举逻辑

    • 节点为Canaditate

    选举准备操作

    • 自增当前的term,
    • 给自己投一票
    • 重置选举超时计时器
      发送RPC投票请求到其他server

    选举中操作

    • 接收到超过半数节点的选票,变为Leader
    • 接收到到来自Leader的日志追加RPC,变回Follower
    • 选举超时前未发生2或3,再次发起选举

    • 节点为 Follower

    状态变更准则

    如果在自身选举超时时间超时前未收到Leader的心跳或者日志追加,也没有给某个Candiate投票,那么自己变成候选人

    投票准则

    • 如果候选人term小于currentTerm ,拒绝投票,并且返回currentTerm让候选人更新
    • 如果voteFor为-1或者恰好等于Candidate,则将候选人的最后一条日志与自己的最后一条日志term进行对比,大于自己则投票,小于自己则拒绝,相等则比较索引

练习: 根据教程结合RAFT论文,实现raft的选举机制


2.2.3.2 心跳通知与日志追加(AppendEntires)

请求参数(AppendEntriesArgs)

参数解释
termLeader任期号
leaderIdLeaderId
prevLogIndex新日志之前的那条日志索引
prevLogTerm新日志之前的那条日志任期
entries需要被追加与保存的日志条目列表(做心跳时日志条目为空)
leaderCommitLeader已知的已经提交的最高的日志条目索引

响应参数(AppendEntriesReply)

参数解释
term当前任期
success结果为真,则说明follower的所有日志与prevLogIndex,preLogTerm匹配
  • 具体逻辑

前置逻辑

  • 如果接收到的RPC请求或请求中,term >currentTerm,那么更新currentTerm = term,并变更状态为follower. 这一点体现了term的逻辑时钟的作用
  • 如果commitIndex > LastApplied,那么LastApplied++,将索引为LastApplied的日志应用到状态机

节点为Leader

  • 选举成功成为领导人之后,立即发送心跳(空日志)到其他节点,按照一定时间间隔不断发送,避免其他节点超时触发选举
  • 接收到client的请求,先附加日志条目到本地日志中,在条目被引用到状态机后响应client
  • 对于一个follower,如果最后一条日志的索引大于等于nextIndex,则发送从nextIndex开始的所有日志条目

追加成功: 更新nextIndex和matchIndex中follower对于的值
追加失败: 发送日志冲突,Leader减少nextIndex进行重发尝试
当半数节点已经收到某条日志,即存在一个数N 满足N>commitIndex,且大多数的matchIndex[i]>=N成立,且log[N].term == currentTerm成立,那么更新commitindex为N

节点为follower

  • 如果Leader的term小于 自身的term ,返回false
  • 在接收者的日志中,如果能够找到一个日志条目的prevLogIndex以及prevLogTerm与请求中的相同,那么继续执行,否则返回false
  • 如果一个已经存在的条目和待追加日志条目发送冲突,即index相同,term不相同,那么删除该已经存在的日志以及其之后的所有日志,保证Leader的绝对权威
  • 追加日志中不存在的所有新日志
    如果leadcommit > commitIndex,即领导者的已知提交到最高日志索引大于接收者的已知的最高的日志索引,则把commitIndex重置为 min(leadercommit,最新日志的索引)


2.2.3 RAFT优化

2.2.3.1 日志快照

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

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

相关文章

【Google I/O 2023】PaLM2 大语言模型与 Bard 使用体验

欢迎关注【youcans的学习笔记】原创作品,火热更新中 【Google I/O 2023】PaLM2 大语言模型与 Bard 使用体验 1. PaLM2 大型语言模型1.1 谷歌发布 PaLM21.2 PaLM2 的功能与性能 2. 基于 PaLM2 的谷歌 AI 产品2.1 智能助手 Duet AI2.2 Gmail:帮我写邮件2.3…

【JMM】保证线程间的可见性,还只知道volatile?

本文目录 前言 举例🌰 情形1 int->Integer 情形2 System.out.println() 情形3 storeFence() 情形4 Thread.yield() 情形5 LockSupport.unpark() 情形6 增长循环内代码执行时间 总结分析 volatile分析 字节码解释器实现 模版解释器实现 其他情形…

利用腾讯云cos如何自建一个上传图片源站

目标总纲 对于一个新手来说,做一个东西,最困难的不是怎么做,而是做什么,接下来我会将任务进行拆分,让新手可以轻松"上路"。 在腾讯云上创建一个cos桶上传图片到cos桶在浏览器中如何访问图片(开…

ChatGPT都有些什么好玩的玩法?

ChatGPT是一个智能聊天机器人,可以进行多种有趣的玩法,以下是其中一些: 1. 问答游戏:ChatGPT可以回答各种问题,你可以和它玩问答游戏,看看谁更聪明。 2. 聊天互动:ChatGPT可以进行自然语言聊天…

【C++STL】AVL树(更新中)

前言 二叉搜索树是具有特殊存储结构的树,任意根节点的左子树的所有节点值都比根节点的值小,右子树的所有节点值都比根节点大。 这种特殊的存储结构使得查找的效率大大提升,为logN。但是还有缺陷。 因为二叉搜索树的构建是一个节点一个节点的…

MySQL中去重 distinct 和 group by 是如何去重的

1:测试数据 CREATE TABLE student (stu_no VARCHAR(40) NOT NULL,name VARCHAR(100) NOT NULL );insert into student values(1,name1); insert into student values(2,name2); insert into student values(3,name1); insert into student values(4,name2); i…

【C++初阶】:类与对象(下)

类与对象 一.再谈构造函数1.初始化列表(构造函数的一部分)2.explicit关键字 二.static成员三.友元1.友元函数2.友元类 四.内部类五.匿名对象六.再次理解类与对象 一.再谈构造函数 1.初始化列表(构造函数的一部分) 我们可以直接在…

2023数维杯ABC题思路代码分析

已完成全部可以领取,详情看文末!!! 数维杯A题思路 A题是这次比赛比较难的题目,地下水系统水体污染问题,他给出了我们一些行为特征,污染物的行为特征主要涉及对流迁移、水动力弥散、吸附及阻滞…

一、走进easyUI的世界

1.什么是easyUI? jQuery EasyUI是一组基于jQuery的UI插件集合体,而jQuery EasyUI的目标就是帮助web开发者更轻松的打造出功能丰富并且美观的UI界面。开发者不需要编写复杂的javascript,也不需要对css样式有深入的了解,开发者需要…

matlab实验三程序设计与优化

一、实验目的及要求 一、实验的目的与要求 1、掌握 MATLAB的函数 2、掌握 MATLAB的程序流 3、掌握 MATLAB脚本和函数文件的编写 4、熟悉基于矩阵的程序设计与优化 二、实验原理 1、MATLAB的M文件:脚本文件与函数文件; 2、MATLAB程序流:input…

【企业信息化】第2集 免费开源ERP: Odoo 16 销售管理系统

文章目录 前言一、概览二、使用功能1.通过清晰报价提高销售效率2.创建专业报价单3.管理订单及合同4.简化沟通5.维护产品&价格6.直观的报告7.集成 三、总结 前言 世界排名第一的免费开源ERP: Odoo 16 销售管理系统。通过Odoo Sign应用程序和在线支付,发送报价。…

“极乐净土”时隔7年再度席卷B站,二次元魂藏不住了!

七年前,日本知名歌手美依礼芽发行一曲《极乐净土》,搭配歌曲的宅舞视频燃起了众多二次元魂,翻跳投稿纷至沓来。 可以说,她是许多老二次元人的回忆,也是一个时代的标记。 当时,《极乐净土》横空出世&#…

为什么需要边缘计算?哪些场景需要边缘计算?

为什么需要边缘计算? 边缘计算(Edge Computing)是一种将数据处理和计算功能移到接近数据源头的边缘设备上进行的计算模式。相比传统的云计算模式,边缘计算能够在接近数据源头的地方进行实时的数据处理,这为计算机视觉…

前端vue3一键打包发布

一键打包发布可以分为两种,一是本地代码,编译打包后发布至服务器,二是直接在服务器上拉去代码打包发布至指定目录中。 两种各有使用场景,第一种是前端开发自己调试发布用的比较多,第二种是测试或者其他人员用的多&…

java 二维数组的定义及操作

二维数组的定义有很多方式: 第一种方式: 数据类型[][] 数组名 new数据类型[行的个数][列的个数]; 下面以第一种方式声明一个数组,如下所示。 int[][] xx new int[3][4]; 表示有三行,每行方四个数据第二种方式: 数据类…

甘特图控件DHTMLX Gantt入门使用教程【引入】:dhtmlxGantt 与Node.js(上)

DHTMLX Gantt是用于跨浏览器和跨平台应用程序的功能齐全的Gantt图表。可满足项目管理应用程序的大部分开发需求,具备完善的甘特图图表库,功能强大,价格便宜,提供丰富而灵活的JavaScript API接口,与各种服务器端技术&am…

Vue3-黑马(三)

目录: (1)vue3-基础-计算属性 (2) vue3-基础-xhr-基本使用 (3)vue3-基础-xhr-promise改造 (1)vue3-基础-计算属性 上面有重复的代码,用计算属性&#xff0…

Kali工具集简介

Kali Linux提供了数种经过定制的专门为渗透测试设计的工具。工具都会按下图中下拉选单所示的方式按组分类聚合。了解工具是做渗透测试第一个认知。 口Information Gathering(信息收集) 这些都是侦察工具,用来收集目标网络和设备的数据。在这类工具中,从找出设备的工具到查看使…

大数据分析案例-基于高斯朴素贝叶斯算法构建良恶性肿瘤识别器

🤵‍♂️ 个人主页:艾派森的个人主页 ✍🏻作者简介:Python学习者 🐋 希望大家多多支持,我们一起进步!😄 如果文章对你有帮助的话, 欢迎评论 💬点赞&#x1f4…

时间复杂度和空间复杂度的七七八八

文章目录 时间空间复杂度1. 时间空间复杂度的重要性(作用)2. 时间复杂度和大O表示法1)算法图解2)代码随想录3)王道《数据结构》 3. 大O指的是最糟的情形和一般的情形1)大O表示的是一般情况,并不是严格的上界2&#xff…