详解共识算法的Raft算法模拟数

详解,共识,算法,raft,模拟 · 浏览次数 : 62

小编点评

**Raft算法模拟数** **简介** Raft算法是一种分布式共识算法,用于解决分布式系统中的一致性问题。本文章分享华为云社区《共识算法之Raft算法模拟数》,作者: TiAmoZhang 。 **Raft集群结构** Raft集群由三个成员组成: * Leader:负责维护集群中的 leadership,接收来自follower的请求并执行状态转移。 * Followers:负责从 leader 获取数据并执行数据处理。 ** leader选举** 在集群启动时,每个成员都处于 Follower 状态。成员A的心跳超时时间最短,最先进入选举状态,修改自己的状态为 Candidate,并增加自己的任期编号为1,发起请求投票消息。 **日志复制** 日志复制是一个一阶段协商过程,其中,日志项的提交操作由下一轮协商或心跳消息来代替完成。日志复制消息除了会包含需要复制日志项的相关信息外,通常会携带Leader的 committedIndex参数,标示着最后一个已提交的日志索引。 **AppendEntries消息** AppendEntries消息用于追加日志项到本地日志中。每个Follower的本地都维护了committedIndex,Follower可以对比Leader的committedIndex来推进自己的提交操作。 **日志对齐** 当多个follower对同一个日志项进行提交时,它们需要进行日志对齐才能保持数据一致性。在raft中,这个步骤可由AppendEntries消息完成。 **结论** Raft算法是一种分布式共识算法,可以用于解决分布式系统中的一致性问题。

正文

摘要:Raft算法是一种分布式共识算法,用于解决分布式系统中的一致性问题。

本文分享自华为云社区《共识算法之Raft算法模拟数》,作者: TiAmoZhang 。

01、Leader选举

存在A、B、C三个成员组成的Raft集群,刚启动时,每个成员都处于Follower状态,其中,成员A心跳超时为110ms,成员B心跳超时为150ms,成员C心跳超时为130ms,其他相关信息如图1所示。

■ 图1 Raft模拟初始状态

由于集群中不存在Leader,A、B、C三个成员都不会收到来自Leader的心跳信息。其中,成员A的超时最短,最先进入选举状态,修改自己的状态为Candidate,并增加自己的任期编号为1,发起请求投票消息,如图2所示。

■ 图2 请求投票

成员A通过RequestVote广播自己的选票给成员B、C,选票描述了成员A所拥有的数据,其包含成员A所处的term及最新的日志索引。成员B、C根据投票规则处理RequestVote消息。

term大的成员拒绝投票给term小的成员。

日志索引大的成员拒绝投票给日志索引小的成员。

一个term内只投出一张选票,采用先来先获得投票的原则。

很明显,成员B、C的term小于成员A的term,也不存在比成员A日志索引更大的日志索引,并且term为1的选票还没有投给其他成员,因此成员B、C将term为1的选票投给成员A并更新自己的term为1。

成员A获得包括自己在内的3张选票,赢得大多数选票,成员A晋升为Leader,并向其他成员发送心跳信息,维护自己的领导地位,如图3所示。

■ 图3 Leader晋升示意

如果成员A在等待投票超过约定的时间内没有收到多数派的选票,则会重置自己的超时,并结束本次选举进程。接着会有其他成员在等待心跳超时后发起Leader选举,在当前案例中,发起Leader选举的顺序为A→C→B。

可能因为网络问题,使集群中的所有成员又发起了一轮选举,但是都没有获得多数派的选票,因此会随机产生新的超时,开始下一个循环的选举。

02、日志复制

日志复制是一个一阶段协商的过程,其中,日志项的提交操作由下一轮协商或者心跳消息来代替完成。因此处理事务请求,Raft只需要发送一轮AppendEntries消息即可。

AppendEntries消息除了会包含需要复制日志项的相关信息外,通常会携带Leader的committedIndex参数,标示着最后一个已提交的日志索引。每个Follower的本地都维护了committedIndex,Follower可以对比Leader的committedIndex来推进自己的提交操作。

接着如图3所示的示例,一个三个成员组成的集群,成员A为Leader,成员B和C为Follower,并且在集群中未提交任何日志项。Leader收到客户端发送的Add请求后,Leader和Follower依次执行以下步骤,如图4所示。

■ 图4 日志复制-复制

(1)Leader将其封装成日志项追加到本地的日志中,日志索引为1。

(2)Leader通过AppendEntries(0, <1, Add>)消息时将日志项广播给所有的Follower。其中:

  • 第一个参数为committedIndex,即Leader最后提交的日志索引。
  • 第二个参数为Leader所处的日志索引,即Add日志项的索引。
  • 第三个参数为事务操作指令,即客户端的指令。

(3)Follower收到消息,将日志项追加到本地的日志中。

此时,成员A、B、C都拥有日志项Add且都已在索引为1上完成了持久化。Follower在处理完AppendEntries消息后需要回复ACK消息给Leader,代表接受该日志项。Leader收到多数派的ACK消息后,可以在本地提交该日志项并执行状态转移,之后将执行结果返回给客户端,如图5所示。

■ 图5 日志复制-回复

在当前场景中,成员A提交了索引为1的日志项,成员B、C仅仅拥有索引为1的日志项的所有信息但并未提交。成员B、C需要等待下一次AppendEntries消息,根据其committedIndex推进索引为1的日志项的提交操作。以心跳的AppendEntries消息为例,该AppendEntries消息仅携带了committedIndex,此时Leader已经提交了索引为1的日志项,因此committedIndex为1。Follower则可以提交索引为1及其之前的所有日志项,如图6所示。

■ 图6 日志复制-心跳

03、日志对齐

我们使用<term, logIndex>表示一个日志项,如表1所示为Follower E的日志索引3和Follower D的日志索引4,与当前Leader处理不一致的情况。出现这种情况可能是Follower E和Follower D曾经当选过Leader,并且在自己的term上提出了日志索引为3和4的日志项后立即宕机造成的。

■ 表1 日志对齐

要使Follower E和Follower D与Leader数据保持一致,大致步骤分为两步:寻找nextIndex,复制nextIndex及其之后的日志项。在Raft中,这个步骤均可由AppendEntries消息来完成。这里以Follower E成员为例,交互细节如下:

(1)Leader为Follower E初始化nextIndex,nextIndex=lastLogIndex+1,即nextIndex=6+1=7。

(2)Leader通过AppendEntries发送探测消息,携带preLogIndex(nextIndex-1)及preLogTerm,其中,preLogIndex=6,preLogTerm=3。

(3)Follower收到探测消息,对比索引为6的日志项,返回失败的响应给Leader并携带lastLogIndex=3。

(4)Leader收到失败的响应,更新nextIndex=lastLogIndexmsg+1,即nextIndex=4。

(5)Leader发送下一轮的探测消息,其中,preLogIndex=3,preLogTerm=2。

(6)Follower收到探测消息,对比索引为3的日志项,返回失败的响应给Leader并携带lastLogIndex=3。

(7)Leader收到失败的响应,此时lastLogIndexmsg+1 ≤ nextIndex,则nextIndex单调递减为3。

(8)Leader发送下一轮的探测消息,其中,preLogIndex=2,preLogTerm=1。

(9)Follower收到探测消息,对比索引为2的日志项,返回探测成功的响应给Leader。

(10)Leader在成功探测到nextIndex之后,通过AppendEntries消息从nextIndex开始发送索引为3的日志项给Follower。

(11)Follower将以Leader的数据为准,覆盖本地的日志项并返回处理成功的响应给Leader。

(12)Leader收到成功响应后,单调递增nextIndex,继续发送下一个日志项。直到nextIndex等于Leader的lastLogIndex,意味着该Follower拥有Leader所有的数据,本次日志对齐即完成。

 

点击关注,第一时间了解华为云新鲜技术~

与详解共识算法的Raft算法模拟数相似的内容:

详解共识算法的Raft算法模拟数

摘要:Raft算法是一种分布式共识算法,用于解决分布式系统中的一致性问题。 本文分享自华为云社区《共识算法之Raft算法模拟数》,作者: TiAmoZhang 。 01、Leader选举 存在A、B、C三个成员组成的Raft集群,刚启动时,每个成员都处于Follower状态,其中,成员A心跳超时为1

详解kubernetes的发布方式

项目的发布方式 蓝绿发布:不停止旧版本,直接部署新版本 灰度发布:旧版本和新版本共存 滚动更新:平滑地将服务更新 蓝绿发布 蓝绿部署就是不停止旧版本,直接部署新版本 部署过程: 部署v1的应用(初始状态) :所有外部请求都会进入此版本 部署版本2的应用:新版的应用 如果版本2测试正常,就可以将流量切

[转帖]k8s之PV、PVC、StorageClass详解

https://zhuanlan.zhihu.com/p/128552232 导读 上一篇写了共享存储的概述以及一个简单的案例演示。这一篇就写一下PV和PVC。 PV是对底层网络共享存储的抽象,将共享存储定义为一种“资源”,比如Node也是容器应用可以消费的资源。PV由管理员创建和配置,与共享存储的

架构师日记-到底该如何搭建一个新系统

本文详细介绍了搭建系统工程架构时需要关注的几个重要方面。基于产品的价值,做出决策。并从系统工程架构的演进、技术方案的选型、系统规范共识的达成等方面入手,对实施过程中的常见问题给出了解决思路。

[转帖]ELF文件详解

一、ELF概述 1、ELF的定义 ELF(Executable and Linkable Format)文件是一种目标文件格式,常见的ELF格式文件包括:可执行文件、可重定位文件(.o)、共享目标文件(.so)、核心转储文件等。 ELF主要用于Linux平台,Windows下是PE/COFF格式。

Python并行运算——threading库详解(持续更新)

0. 写在前面:进程和线程 博文参考: Python的并行(持续更新)_python 并行-CSDN博客 《Python并行编程 中文版》 一些相关概念请见上一篇博文。 1. 在Python中使用线程 1.1 多线程简介 线程是独立的处理流程,可以和系统的其他线程并行或并发地执行。 多线程可以共享数

Istio Ambient Mesh七层服务治理图文详解

摘要:本文主要集中剖析Ambient mesh七层服务治理相关内容。 本文分享自华为云社区《Istio Ambient Mesh七层服务治理图文详解》,作者:华为云云原生团队。 由于Ambient mesh的工作原理比较复杂,我们在上一篇文章《深度剖析!Istio共享代理新模式Ambient Mes

ThreadLocal 源码浅析

多线程在访问同一个共享变量时很可能会出现并发问题,特别是在多线程对共享变量进入写入时,那么除了加锁还有其他方法避免并发问题吗?本文将详细讲解 ThreadLocal 的使用及其源码。

[转帖]比快更快的 ELK 8 安装使用指南-Elasticsearch,Kibana,Logstash

https://juejin.cn/post/7133907643386560519 携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第23天,点击查看活动详情 Elastic 8 的新特性 Elastic 8.0 版号称 比快更快 ,其新特性可参考 Elastic 官方博客:

吐血整理如何在Google Earth Engine上写循环 五个代码实例详细拆解

在这里同步一篇本人的原创文章。原文发布于2023年发布在知乎专栏,转移过来时略有修改。全文共计3万余字,希望帮助到GEE小白快速进阶。 引言 这篇文章主要解答GEE中.map()和.iterate()函数的用法。 首先解答一个疑问,为什么需要自己写循环?确实,GEE 为各种数据类型提供了无数常用的内