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

分布式与一致性协议之Raft算法(一)

Raft算法

概述

Raft算法属于Multi-Paxos算法,它在兰伯特Multi-Paxos思想的基础上做了一些简化和限制,比如日志必须是连续的,只支持领导者(Leader)、跟随者(Follwer)和候选人(Candidate)3种状态。在理解和算法实现上,Raft算法相对容易许多。
除此之外,Raft算法是现在分布式系统首选的共识算法。绝大多数选用Paxos算法的系统(比如Chubby、Spanner)都是在Raft算法发布前开发的,当时没有其他选择;而全新的系统大多选择了Raft算法(比如Etcd、Consul、CockroachDB)。
掌握了Raft算法,我们就可以得心应手地满足绝大部分场景的容错和一致性需求,比如分布式配置系统、分布式NoSQL存储等,轻松突破系统的单机限制。
如果要用一句话概括Raft算法,我觉得是这样的:从本质上说,Raft算法是通过一切以领导者为准的方式实现一系列值得共识和个节点日志的一致。这句话比较抽象,做个比喻:领导者就是Raft算法中的"霸道总裁",通过霸道的"一切以我为准"的方式。决定了日志中命令的值,也实现了个节点日志的一致。后面会以领导者选举、日志赋值、成员变更为核心,讲解Raft算法的原理。

在正式介绍之前,我们先来看一道思考题。
假设我们有一个由节点A、B、C组成的Raft集群(如图所示),因为Raft算法是一切以领导者为准,所以如果集群中出现了多个领导者,就会出现不知道谁来做主的问题。在这样一个有多个节点的集群中,在节点故障、分区容错等异常情况下,Raft算法应该如何保证在同一个时间内集群中只有一个领导者呢?
在这里插入图片描述

Raft是如何选举领导者的

既然要选举领导者,要从哪些成员中选举呢?除了领导者,Raft算法还支持哪些成员身份呢?这是需要掌握的最基础的背景知识。

有哪些成员身份

在这里插入图片描述

成员身份,又叫作服务器节点状态。Raft算法支持跟随者、候选人和领导者3种状态。为了方便理解,
我们使用不同的图形表示不同的状态,如图u宋史,在任何时候,每一个服务器节点都处于这3个状态中的其中1个

  • 1.跟随者:相当于普通群众,默默地接收和处理来自领导者的消息,当领导者心跳信息超时的时候,它会主动站出来,推荐自己当候选人

  • 2.候选人:候选人将向其他节点发送请求投票(RequestVote) RPC消息,通知其他节点来投票,如果它赢得了大多数选票,那么它将晋升为领导者

  • 3.领导者:一切以我为准,平常的主要工作包含三部分,处理写请求、管理日志复制和不断发送心跳信息,通知其他节点"我是领导者,你们现在不要发起新的选举,找个新领导者来替代我"

  • 需要注意的是,Raft算法是强领导者模型,集群中只能有一个"霸道总裁"。

选举领导者的过程

那么如何从3个成员中选出领导者呢?
首先,在初始状态下,集群中所有的节点都处于跟随者的状态,如图所示。
在这里插入图片描述

Raft算法实现了随机超时时间的特性。也就是说,每个节点等待领导者节点心跳信息的超时时间间隔是随机的。
通过上图可以看到,集群中没有领导者,而节点A的等待超时时间最小(150ms),所以它会最先因为没有等到领导者的心跳信息而超时。
这个时候,节点A会增加自己的任期编号,并推荐自己为候选人,先给自己投一张选票,然后先其他阶段发送请求投票RPC消息,请他们选举自己为领导者,如图所示在这里插入图片描述

如果其他节点接收到候选人A的请求投票RPC消息,且在编号为1的这届任期内,它也还没有投过票,那么它将把选票投给节点A,并增加自己的任期编号,如图所示。
在这里插入图片描述

如果候选人在选举超时时间内赢得了大多数选票,那么它就会成为本届任期内新的领导者,如图所示。在这里插入图片描述

节点A当选领导者后,将周期性的发送心跳消息,通知其他服务器"我是领导者",阻止跟随者发起新的选举、篡权。在这里插入图片描述

如图所示,看到这里,你是不是发现领导者选举很容易理解?它与现实中地议会选举也很类似?当然,你可能还是会对一些细节产生疑问,比如:

  • 1.节点间是如何通信地?
  • 2.什么是任期?
  • 3.选举有哪些规则
  • 4.随机超时时间又是什么

选举过程四连问

老话说,细节是魔鬼。这些细节也是大家在学习Raft算法时比较难掌握地,所以这里有必要具体分析一下。一步步来

节点间如何通信

在Raft算法中,服务器节点采用地沟通方式是远程过程调用(RPC),在领导者选举中,我们需要用到这样两类RPC:

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

需要注意的是,日志复制RPC只能由领导者发起,这是实现强领导者模型的关键之一,理解这一点有助于后续更好地理解日志复制,以及如何实现日志的一致

相关文章:

分布式与一致性协议之Raft算法(一)

Raft算法 概述 Raft算法属于Multi-Paxos算法,它在兰伯特Multi-Paxos思想的基础上做了一些简化和限制,比如日志必须是连续的,只支持领导者(Leader)、跟随者(Follwer)和候选人(Candidate)3种状态。在理解和算法实现上,Raft算法相对…...

从自定义一个作用域开始来了解SpringBean的作用域

你好,这里是codetrend专栏“Spring6全攻略”。 在 Spring 框架中,Bean 的作用域(Scope)定义了 Bean 实例在容器中如何创建、管理和销毁的策略。 Spring 提供了多种 Bean 作用域,每种作用域都有其特定的生命周期和适用…...

Android 编译文件简述(Android.mk)

Android 编译文件简述(Android.mk) Android.mk 文件是 Android 构建系统中的一种构建配置文件,使用 GNU Make 语法,用于定义 Android 项目中的模块、库、应用程序、JNI 代码等的编译和链接方式。每个 Android.mk 文件通常对应一个目录,代表构建系统应该如何处理该目录下的源…...

[React] 手动实现CountTo 数字滚动效果

这个CountTo组件npmjs里当然有大把的依赖存在,不过今天我们不需要借助任何三方依赖,造个轮子来手动实现这个组件。 通过研究其他count to插件我们可以发现,数字滚动效果主要依赖于requestAnimationFrame 通过js帧来让数字动起来,…...

9.Admin后台系统

9. Admin后台系统 Admin后台系统也称为网站后台管理系统, 主要对网站的信息进行管理, 如文字, 图片, 影音和其他日常使用的文件的发布, 更新, 删除等操作, 也包括功能信息的统计和管理, 如用户信息, 订单信息和访客信息等. 简单来说, 它是对网站数据库和文件进行快速操作和管…...

redis之集群

一.redis主从模式和redis集群模式的区别 redis主从模式:所有节点上的数据一致,但是key过多会影响性能 redis集群模式:将数据分散到多个redis节点,数据分片存储,提高了redis的吞吐量 二.redis cluster集群的特点 数据分片 多个存储入…...

#9松桑前端后花园周刊-React19beta、TS5.5beta、Node22.1.0、const滥用、jsDelivr、douyin-vue

行业动态 Mozilla 提供 Firefox 的 ARM64 Linux二进制文件 此前一直由发行版开发者或其他第三方提供,目前Mozilla提供了nightly版本,正式版仍需要全面测试后再推出。 发布 React 19 Beta 此测试版用于为 React 19 做准备的库。React团队概述React 19…...

STM32中UART通信的完整C语言代码范例

UART(通用异步收发器)是STM32微控制器中常用的外设,用于与其他设备进行串行通信。本文将提供一个完整的C语言代码范例,演示如何在STM32中使用UART进行数据传输。 硬件配置 在开始编写代码之前,需要确保以下硬件配置&…...

【ITK统计】第一期 分类器

很高兴在雪易的CSDN遇见你 VTK技术爱好者 QQ:870202403 公众号:VTK忠粉 前言 本文分享ITK中的分类器及其使用情况,希望对各位小伙伴有所帮助! 感谢各位小伙伴的点赞+关注,小易会继续努力分享,一起进步! 你的点赞就是我的动力(^U^)ノ~YO 在统计分…...

51单片机两个中断及中断嵌套

文章目录 前言一、中断嵌套是什么?二、两个同级别中断2.1 中断运行关系2.2 测试程序 三、两个不同级别中断实现中断嵌套3.1 中断运行关系3.2 测试程序 总结 前言 提示:这里可以添加本文要记录的大概内容: 课程需要: 提示&#x…...

VUE 监视数据原理

1、如何监测对象中的数据? 通过setter实现监视,且要在new vue时就传入监测的数据 (1)对象中后加的属性,vue默认不做响应式处理 (2)如需给后添加的属性做响应式,请使用如下API&#x…...

Thinkphp使用dd()函数

用过Laravel框架的同学都知道在调试代码的时候使用dd()函数打印变量非常方便,在ThinkPHP6及以上的版本框架中也默认加上了这个函数。但是在ThinkPHP5或更低版本的框架中,dd 并不是一个内置的方法,不过我们可以手动添加这个函数,步…...

Git使用指北

目录 创建一个Git仓库本地仓库添加文件文件提交到本地仓库缓冲区添加远程仓库地址本地仓库推送到远程仓库创建新的分支拉取代码同步删除缓冲区的文件,远程仓库的文件.gitignore文件 创建一个Git仓库 Git仓库分为远程和本地两种,远程仓库如Githu上创建的…...

STM32G030F6P6TR 芯片TSSOP20 MCU单片机微控制器芯片

STM32G030F6P6TR 在物联网(IoT)设备中的典型应用案例包括但不限于以下几个方面: 1. 环境监测系统: 使用传感器来监测温度、湿度、气压等环境因素,并通过无线通信模块将数据发送到中央服务器或云端平台进行分析和监控。…...

零基础入门学习Python第二阶01生成式(推导式),数据结构

Python语言进阶 重要知识点 生成式(推导式)的用法 prices {AAPL: 191.88,GOOG: 1186.96,IBM: 149.24,ORCL: 48.44,ACN: 166.89,FB: 208.09,SYMC: 21.29}# 用股票价格大于100元的股票构造一个新的字典prices2 {key: value for key, value in prices.i…...

Java面试题:多线程3

CAS Compare and Swap(比较再交换) 体现了一种乐观锁的思想,在无锁情况下保证线程操作共享数据的原子性. 线程A和线程B对主内存中的变量c同时进行修改 在线程A中存在预期值a,修改后的更新值a1 在线程B中存在预期值b,修改后的更新值b1 当且仅当预期值和主内存中的变量值相等…...

【QEMU系统分析之实例篇(十八)】

系列文章目录 第十八章 QEMU系统仿真的机器创建分析实例 文章目录 系列文章目录第十八章 QEMU系统仿真的机器创建分析实例 前言一、QEMU是什么?二、QEMU系统仿真的机器创建分析实例1.系统仿真的命令行参数2.创建后期后端驱动qemu_create_late_backends()qtest_serv…...

pyside6的调色板QPalette的简单应用

使用调色板需要先导入:from PySide6.QtGui import QPalette 调色板QPalette的源代码: class QPalette(Shiboken.Object):class ColorGroup(enum.Enum):Active : QPalette.ColorGroup ... # 0x0Normal : QPalette.ColorGrou…...

苍穹外卖项目

Day01 收获 补习git Git学习之路-CSDN博客 nginx 作用:反向代理和负载均衡 swagger Swagger 与 Yapi Swagger: 可以自动的帮助开发人员生成接口文档,并对接口进行测试。 项目接口文档网址: http://localhost:8080/doc.html Da…...

error: Execution was interrupted, reason: signal SIGABRT

c json解析时&#xff0c; error: Execution was interrupted, reason: signal SIGABRT const Json::Value points root["shapes"]; if (points.isArray()) { for (unsigned int i 0; i < points.size(); i) { std::cout << " - [" <<…...

装饰模式(Decorator Pattern)重构java邮件发奖系统实战

前言 现在我们有个如下的需求&#xff0c;设计一个邮件发奖的小系统&#xff0c; 需求 1.数据验证 → 2. 敏感信息加密 → 3. 日志记录 → 4. 实际发送邮件 装饰器模式&#xff08;Decorator Pattern&#xff09;允许向一个现有的对象添加新的功能&#xff0c;同时又不改变其…...

React Native 导航系统实战(React Navigation)

导航系统实战&#xff08;React Navigation&#xff09; React Navigation 是 React Native 应用中最常用的导航库之一&#xff0c;它提供了多种导航模式&#xff0c;如堆栈导航&#xff08;Stack Navigator&#xff09;、标签导航&#xff08;Tab Navigator&#xff09;和抽屉…...

【大模型RAG】Docker 一键部署 Milvus 完整攻略

本文概要 Milvus 2.5 Stand-alone 版可通过 Docker 在几分钟内完成安装&#xff1b;只需暴露 19530&#xff08;gRPC&#xff09;与 9091&#xff08;HTTP/WebUI&#xff09;两个端口&#xff0c;即可让本地电脑通过 PyMilvus 或浏览器访问远程 Linux 服务器上的 Milvus。下面…...

渲染学进阶内容——模型

最近在写模组的时候发现渲染器里面离不开模型的定义,在渲染的第二篇文章中简单的讲解了一下关于模型部分的内容,其实不管是方块还是方块实体,都离不开模型的内容 🧱 一、CubeListBuilder 功能解析 CubeListBuilder 是 Minecraft Java 版模型系统的核心构建器,用于动态创…...

OkHttp 中实现断点续传 demo

在 OkHttp 中实现断点续传主要通过以下步骤完成&#xff0c;核心是利用 HTTP 协议的 Range 请求头指定下载范围&#xff1a; 实现原理 Range 请求头&#xff1a;向服务器请求文件的特定字节范围&#xff08;如 Range: bytes1024-&#xff09; 本地文件记录&#xff1a;保存已…...

C++ 基础特性深度解析

目录 引言 一、命名空间&#xff08;namespace&#xff09; C 中的命名空间​ 与 C 语言的对比​ 二、缺省参数​ C 中的缺省参数​ 与 C 语言的对比​ 三、引用&#xff08;reference&#xff09;​ C 中的引用​ 与 C 语言的对比​ 四、inline&#xff08;内联函数…...

Python如何给视频添加音频和字幕

在Python中&#xff0c;给视频添加音频和字幕可以使用电影文件处理库MoviePy和字幕处理库Subtitles。下面将详细介绍如何使用这些库来实现视频的音频和字幕添加&#xff0c;包括必要的代码示例和详细解释。 环境准备 在开始之前&#xff0c;需要安装以下Python库&#xff1a;…...

Spring AI 入门:Java 开发者的生成式 AI 实践之路

一、Spring AI 简介 在人工智能技术快速迭代的今天&#xff0c;Spring AI 作为 Spring 生态系统的新生力量&#xff0c;正在成为 Java 开发者拥抱生成式 AI 的最佳选择。该框架通过模块化设计实现了与主流 AI 服务&#xff08;如 OpenAI、Anthropic&#xff09;的无缝对接&…...

力扣-35.搜索插入位置

题目描述 给定一个排序数组和一个目标值&#xff0c;在数组中找到目标值&#xff0c;并返回其索引。如果目标值不存在于数组中&#xff0c;返回它将会被按顺序插入的位置。 请必须使用时间复杂度为 O(log n) 的算法。 class Solution {public int searchInsert(int[] nums, …...

Python Ovito统计金刚石结构数量

大家好,我是小马老师。 本文介绍python ovito方法统计金刚石结构的方法。 Ovito Identify diamond structure命令可以识别和统计金刚石结构,但是无法直接输出结构的变化情况。 本文使用python调用ovito包的方法,可以持续统计各步的金刚石结构,具体代码如下: from ovito…...