Raft-2023的一些笔记(SJTU-ACM-PPCA & MIT 6.5840)

raft,一些,笔记,sjtu,acm,ppca,mit · 浏览次数 : 23

小编点评

**Raft算法简介** Raft算法是一种分布式一致性协议,它用于构建一个可以处理大量连接的网络。网络中有多台服务器,每个服务器都拥有复制数据的部分,并通过领导人选举机制来确保所有服务器上的数据一致。 **核心概念** * **领导者 (Leader):**领导者拥有复制数据的部分,并通过发送指令向其他服务器发送数据。 * **候选者 (Candidate):**候选者会从大多数服务器中获取选票,并从领导者那里接受选择。 * **日志复制 (Log Replication):**当服务器获取数据时,会将其复制给所有其他服务器。 **算法步骤** 1. **领导者选举 (Leader Election):**当服务器启动时,会随机选择一个领导者。 2. **日志复制 (Log Replication):**当服务器获取数据时,会将其复制给所有其他服务器。 3. **选举 (Election):**当领导者无法从大多数服务器中获取选票时,会进入选举阶段。 4. **投票 (Vote):**候选者向其他服务器发送投票请求,要求他们记录他们的投票。 5. **领导者接受投票 (Leader Accepts Vote):**当候选人收集超过一半的投票时,就被选中为领导者。 6. **日志更新 (Log Updates):**当领导者成为领导者时,会更新他们的日志。 7. **数据复制 (Data Replication):**当服务器成为领导者时,会开始复制数据给所有其他服务器。 **关键术语** * **选举 (Election):**当多个服务器无法决定谁是领导者时,就会进行选举。 * **候选人 (Candidate):**当服务器无法成为领导者时,会成为候选人。 * **领导者 (Leader):**拥有复制数据的部分,并通过发送指令向其他服务器发送数据。 * **日志复制 (Log Replication):**当服务器获取数据时,会将其复制给所有其他服务器。 * **一致性 (Consistency):**一致性协议确保所有服务器上的数据保持一致。

正文

Raft算法介绍

这是对Raft算法的一个粗略介绍,来源是Raft (thesecretlivesofdata.com)

前置

首先,我们定义一个节点为一台存储数据的服务器。

我们在体系中有很多这样的节点,也可以有一些客户来发送信息(例如值)给服务器。

显然的,如果只有一个节点,那么一致性(consensus)是非常容易达成的。但如果有很多台服务器,这件事情就没那么简单了(我们可能会面临几台服务器的断网,时钟错乱...这种问题)

这就引出了我们的主题:分布式一致性。本文所要介绍的Raft算法便是为了达成分布式一致性。

领导人、选举机制

我们首先确定一个节点的三个状态:

  • 追随者(follower)

  • 候选者(candidate)

  • 领导者(leader)

在刚开始的时候,所有的节点都处于追随者的状态,如果追随者没有听到领导者的信息,它们可以变成候选者。候选者会向其他节点发出选票请求,这些节点也会返回它们的选票。

如果一个候选人从大多数节点中获得了选票,那它就可以成为领导者。

上述过程被称为领导人选举(Leader Election)

领导者对体系的影响

有了领导者之后,所有对系统的改变信息都会发送到领导者这里。

领导者会将这条信息(例如set 5)存在自己的日志(log)中,作为一条新的条目(entry)。

需要注意的是,尽管这里我们加入了这条日志,但它并没有被提交,所以值并不会被修改,这本质上也是为了维持一致性

这时领导者会把这条指令发给所有的追随者,并持续等待直到大部分追随者都写下了这一条指令(可以想象在写下指令后追随者会发送指令给领导者)。这时候领导人会提交这条指令(改变值)

相似地,领导者会将提交这条指令(改变值)的信息发送给所有追随者。

这时候,可以期待大部分节点之间构成了对系统状态的一致性。

上述过程被称为日志复制(Log Replication)

选举机制

首先值得注意的是,在Raft中有两个计时器来控制选举。

  • 选举倒计时:当选举倒计时(一般为150ms~300ms之间的一个随机数)结束,且在这段时间内追随者没有收到来自领导者的任何信息,那么它会变成一个候选者。自然,这个时候新的一次选举也就开始了

一个候选者先是为自己投票,然后再发送投票请求给其他节点。

如果接收节点在这一轮还没有投票,那么它就会给这个候选者投票。在投票后,该接收节点会重置选举倒计时

如果候选者得到了大部分选票,它就能成为领导者。接下来就是发送各种信息了。这就要联系到第二个计时器了。

  • 心跳倒计时:所有的和系统有关的信息(改变值,修改日志)都是以心跳倒计时为间隔发送的。当然,接收到这些信息也会使得它们的选举倒计时更新。

再选举(当你的领导者宕机了)

 

例如在上图中的情况中,当领导者宕机,A的选举倒计时结束的更快,那么就能更早地发出选票,所以它成为了领导者。

可以期待,如果有几个节点的选举倒计时结束的都很快,那么可能会出现票数相等的情况

分票

 

分票的时候,因为待机时间是随机的,所以可以期待,在剩下的节点中,选举倒计时结束的快的节点可能会成为领导者。

日志复制

正如上文所说,如果我们有了领导者,我们就得经由领导者把所有系统的变化复制到所有节点,而这是通过上文中的”加入日志“请求和”改变值“请求实现的。

我们可以给出日志复制这一过程的步骤:

  1. 客户向领导者发出”修改值“的指令

  2. 领导者把”修改值“这件事情加入日志,作为条目

  3. 领导者向追随者们发出”把‘修改值’这件事情加入日志“的信息

  4. 领导者尝试接收信息,如果接收量超过一半,那么就把值修改了

  5. 领导者将修改的值(或者done的信号)返回给客户

  6. 领导者将”修改值“这件事情发送给追随者们

  7. 追随者们修改值,并返回修改成功这件事情

Raft的鲁棒性

在上述过程中,我们介绍了日志复制的过程。那我们可以思考,如果系统遭受了攻击呢,这时候一致性该如何保证?

我们考察网络中出现隔离的过程:

 

首先,可以想象的是,会有两领导者在不同的任期中(为什么?)。

我们接下来考察两个客户试图更新两个领导者的过程:

 

如果下面的客户想更新值为3,把这条信息传输给了B呢?好像值并不会改变,因为B接收到的追随者并未超过一半。

上面的客户希望把值设置为8,它把信息传给了C。这个操作则可以完成。

现在我们来修复这个隔离。

 

这时候,C的任期高于B,因而B不会当领导者。(退位的充要条件)

同时,A和B会回滚它们的日志来和C的日志相符。

注意!

以上内容只是对于Raft算法的感性理解,在细节上还有很多地方并未完善!!!

任务点:2A

这是第一个任务,主要内容是完成Leader Election(难度:defined as moderate

具体而言,应该选出一个领导者(他在没有出事之前一直都是),如果出事了,选出新的领导人。

提示如下:

  • Raft这个结构体中加入信息,也要开一个LogEntry的结构体

  • RequestVoteArgs/RequestVoteReply中加入信息,并修改Make()来产生一个Go程,使得每个服务器在一段时间没收到他人信息的时候开始领导人选举。同时,在RequestVote()中加入信息来获取投票这一机制。

  • 为了有心跳,定义AppendEntries()这一结构体,并让领导人周期性地发送,同时这一函数也要重置选举倒计时。

  • 用随机化来确保不是所有节点都同时结束冷却。

  • 心跳不能超过10次每秒

  • 测试希望领导人能在5秒内选出来,因而合适的选举倒计时很重要

  • 论文中150ms~300ms的选举倒计时的使用条件是心跳远快于这个时间,所以可能我们的实现中选举倒计时会更长一些,但不能5秒内选不出领导人。

  • 使用Go中的随机库

  • 如果希望等一会儿,就用time.Sleep()

  • 别忘了实现GetState()

  • 实现的方法和结构体必须以大写字母开头,注意warnings

Raft助教指南

论文中的Figure2非常重要。它描述的十分准确,其中的每一条规则都应当被细化完成。

例子:

  1. If election timeout elapses without receiving RPC from current leader or granting vote to candidate: convert to candidate。这意味着两种情况都要变成候选者。

  2. 在收到heartbeat的时候,不应该仅仅把election timer重置,仅仅返回`success`

  3. 在收到hearbeat的时候,不应该把这个条目之后的日志全部重置,因为可能我们告诉了领导者这些条目我们已经拥有,这样做意味着回滚。

  4. 除非严格遵循Figure2,不然很容易有很多错。错误的主要来源:活锁对RPC的不当处理不遵守文档没理解部分术语

活锁

可能说,你的程序每个线程都没阻塞,但是都没有做出实质性的结果(例如一直在选领导,领导一直没选出来等)。可能的例子如下:

  1. 选举倒计时的重置是否恰如Figure2所说?充要条件为收到当前领导(term >= 你)的信息/你要开始一轮选举了/你给别人投票了(如果不投,不用reset)

  2. 什么时候才要开始选举呢?特别地,如果是候选者,且选举倒计时归零,则应该开启新一轮选举。

  3. 注意Rules for Servers。举个例子,如果这一任期中你已经投票了,然后有更高级别任期的RPC发给了你,你应该先减小自己的任期(这也会重置一些东西),接着解决RPC,这可能让你再一次投票

错误的RPC解决方式

这里面有挺多细节的,建议注意以下几点:

  1. 如果一步说要“返回错误”,那么就得立刻返回,并且不用执行下面的任何操作。

  2. (后面的2A好像都用不着了...等待更新) 

 

与Raft-2023的一些笔记(SJTU-ACM-PPCA & MIT 6.5840)相似的内容:

Raft-2023的一些笔记(SJTU-ACM-PPCA & MIT 6.5840)

大概是处于边读边翻译的状态。可以有挺多理解不符合实际情况,接下来读/写的过程中会尽量修正

MIT 6.5840 Raft Implementation(2A, Leader Election)

2022-2023-3 PPCA Raft项目的记录(1)

[转帖]raft 一致性算法

https://cizixs.com/2017/12/04/raft-consensus-algorithm/ 分布式系统和一致性 分布式系统有一个很重要的问题要解决,当一台机器出现问题时,我们希望整个集群还是能够正常运行的,以达到高可用的要求。因为系统的数据是不断变化的,所以要保证集群的数据是同步

[转帖]005、体系结构之TiKV_Raft日志

Raft日志 1、Raft与Multi Raft2、Raft 日志复制2.1、复制流程总览2.2、Propose2.3、Append2.3、Replicate(Append)2.4 Committed2.4 Apply 3、Raft Leader 选举3.1、原理3.2、节点故障Leader(主副本

MIT 6.5840 Raft Implementation(2B, Log Replication)

Raft实现思路+细节(2B) 任务分解 2B中最主要的任务就是进行日志的复制。Raft是一个强领导人的系统,这意味着所有的日志添加都是由领导人发起的,与之相类似的,还有很多其他的结论(它们都是比较显然的),读者可以自行证明。 我们可以这样地分解复制日志的过程 我们首先需要完善Raft结构体的内容。

[转帖]etcd raft模块解析

https://www.cnblogs.com/luohaixian/p/16641100.html 1. Raft简介 raft是一个管理复制式日志的共识算法,它是通过复制日志的方式来保持状态机里的数据是最终一致的。 整体的一个运行描述图: 从图中可以看到由几部分组成,共识模块、日志模块和状态机。

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

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

[转帖]一致性入门之--RAFT论文理解

https://whoiami.github.io/RAFT RAFT 是为了保证一致性的工程实现方法。其想法来自于Paxos,由于Paxos极其难以理解以及高复杂性,在工程上实现难度异常大。Diego Ongaro 和 John Ousterhout 提出了一种便于理解和工程实现的一致性算法,其复

[转帖]Kafka高可用 — KRaft集群搭建

Apache Kafka Raft 是一种共识协议,它的引入是为了消除 Kafka 对 ZooKeeper 的元数据管理的依赖,被社区称之为 Kafka Raft metadata mode,简称 KRaft 模式。本文介绍了KRaft模式及三节点的 KRaft 集群搭建。 1 KRaft介绍 KR

[转帖]Kafka高可用 — KRaft集群搭建

Apache Kafka Raft 是一种共识协议,它的引入是为了消除 Kafka 对 ZooKeeper 的元数据管理的依赖,被社区称之为 Kafka Raft metadata mode,简称 KRaft 模式。本文介绍了KRaft模式及三节点的 KRaft 集群搭建。 1 KRaft介绍 KR