vlambda博客
学习文章列表

Raft 分布式共识算法

每天都是美好的一天!

什么是分布式共识?

在设计分布式系统时,我们必须创建带有分布在多个节点上的软件应用程序的系统,运行时通常需要在不同的节点上运行,以共同做出决策并共享数据。


现实世界中的共识:一群人就某件事达成共识


在分布式共识中,节点集合作为一个连贯的组工作,并且可以在某些成员失败的情况下存活。

为什么选择RAFT?

Raft是一种可靠且相对简单的分布式共识算法,经常在现代软件解决方案中使用,例如Consul,Etcd,RabbitMQ等。

在Raft诞生之前,Paxos(由Leslie Lamport设计)是设计用于分布式共识的最受欢迎的算法之一。因此,许多分布式共识算法都基于 Paxos 或从中得到启发。但是,Paxos是一种非常复杂的算法,难以实现以满足其性能和正确性要求。

Raft 背后的主要动机之一是:设计一种分布式共识算法,该算法可以提高可理解性而又不影响性能和正确性。Raft的作者(Diego Ongaro和John Ousterhout)认为Raft优于 Multi-Paxos 协议,因为它通过保持性能和正确性来增强可理解性。

基本原理

在深入探讨之前,让我们看一下 Raft 共识算法的一些基础知识。Raft 基于领导者驱动的共识模型,其中将选举一位杰出的领导者,而该领导者将完全负责管理集群。

为了了解Raft算法,让我们看一下五个节点之间的共识方案,并了解Raft如何实现它。因此,如图1所示,将在启动过程中选择集群的领导者(S1),并为来自客户端的所有命令/请求提供服务。Raft 集群的所有节点都维护一个分布式日志(复制日志),以存储和提交客户端发出的命令(或日志条目)。领导者接受来自客户端的日志条目,并在 Raft 集群中的所有关注者(S2,S3,S4,S5)之间复制它们。

Raft 分布式共识算法

图1- Raft 集:领导者,关注者,客户和分布式日志

在 Raft 集群中,需要最少数量的节点才能提供预期的级别共识保证。这称为法定人数。在 Raft 集群中执行操作所需的最少投票数为(N / 2 +1),其中N是组中成员总数。因此,在上面的示例中,我们需要至少3个节点才能具有共识保证。

如果由于某些原因无法达到法定数量的节点,则集将变得不可用,并且无法提交任何新日志。Raft 通过解决围绕领导者选举的三个主要子问题,管理分布式日志和算法的安全性功能来解决分布式共识问题。

领导人选举

选举Raft的新领导者是领导者的选举过程。当我们启动一个新的Raft集群或某个领导者不可用时,将通过集群中所有成员节点之间的选举来选举一个新的领导者。因此,在给定的实例中,Raft集的节点可以处于以下任何状态(如图2所示);追随者,候选人或领导者。该负责人是管理的Raft集群全面负责并处理所有传入的客户端的命令。该关注是被动的,他们只是给领导或候选人的要求作出回应。当Raft群组中没有领导者时,任何关注者都可以成为候选人,要求该群组中其他成员投票。

Raft 分布式共识算法

图2— Raft成员的状态转换[1]

在Raft算法中,我们将时间划分为任意间隔,称为term。如图3所示,每学期开始大选,当选领导人服务,直到任期结束,除非有在领导节点出现故障。

Raft 分布式共识算法

图3 — RaftTerms和选举[1]

在某些情况下,在选举期间,两名候选人可能会获得相同的票数(分割投票方案),然后需要立即开始新的选举。term 表示为随时间单调增加的数字,term 值在节点之间进行进程间通信时使用。Raft集中的所有这些节点都使用远程过程调用(RPC)进行通信。

开始选举

Raft使用基于心跳的RPC机制来检测何时开始新的选举。在正常操作期间,领导者会定期向所有可用的跟随者发送(图4)心跳消息。因此,节点以跟随者状态启动,只要它从当前领导者那里收到周期性的心跳,就一直保持在跟随者状态。

Raft 分布式共识算法

图4 —领导者→关注者的周期性心跳

这些心跳基于领导者用来向追随者发送新日志条目的相同消息类型。因此,领导者将没有日志条目的AppendEntries RPC用作心跳消息。如果追随者在一段时间内未收到心跳消息,则会触发选举超时,该选举超时将启动新的选举以选择领导者。

当关注者达到其超时时间时,它将通过以下方式启动选举程序:

  1. 增加当前项。
  2. 为自己投票,并将“ RequestVote” RPC发送给集群中的所有其他人。

如图5所示,在我们的示例中,关注者S1首先达到了选举超时时间,然后成为候选者。然后,它请求其他节点将其投票作为领导者。


Raft 分布式共识算法

图5 —选举过程,RequestVote RPC,投票

  1. S1候选人赢得选举,如果多数节点的投票“是”的 RequestVote 请求。

  2. 在S1等待期间,它可能会从另一个声称是领导者的节点接收到AppendEntries RPC。如果S1的候选 term 低于 AppendEntries RPC 的接收 term,则候选S1放弃并接受另一个节点作为合法领导者。

  3. 拆分投票方案:当有多个关注者同时成为候选人时,任何候选人都无法获得多数。这被称为分裂投票情况。在这种情况下,每个候选人都将超时,并且将触发新的选举。

为了最大程度地减少拆分表决的情况,Raft使用了随机选举超时机制,该机制将随机超时值分配给每个节点。

日志复制

一旦节点成为领导者,它就可以从客户端接收命令/日志条目。使用AppendEntries RPC发送日志条目(图6)。

Raft 分布式共识算法

从客户端收到命令后,领导者尝试在集群中的大多数节点上复制命令。如果复制成功,则将命令提交给集群,并将响应发送回客户端。

在图7中,显示了具有五个节点的Raft集的示例分布式日志。

  • 图的每一行代表给定节点的日志,并对日志进行索引以唯一标识领导者在其余节点上接收和复制的每个命令。
  • 该命令使用语法(x←值)以及前导词的关联 term 表示(为清晰起见,此处每个 term  用不同的颜色表示)。

  • term  编号用于标识日志的不一致。

Raft 分布式共识算法

图7:具有5个节点的Raft集的分布式日志

让我们尝试看看当有一个新命令(y←9)从客户端发送到领导者时,日志复制是如何工作的。因此,如图8所示,在接收到新命令时,所有节点的状态都不一致,因为它们具有相同的日志条目,并在2处提交索引。
  • 领导将命令附加到日志,并使用该命令广播AppendEntries RPC。

  • 每个节点都在本地申请条目并成功答复。

  • 当大多数跟随者节点已在本地成功提交日志条目时,领导者将提交命令并将成功响应发送回客户端。

  • 当领导者提交日志条目时,它也会更新提交索引(在本示例中为3),并且下一条AppendEntries广播消息会将更新的提交索引复制到所有跟随者节点。

  • 当领导者提交条目时,它还将在当前日志索引之前提交所有全部内容。

图8:成功条件的日志复制过程

如果某些节点不可用于接收日志条目或消息在运行中丢失,则日志中可能存在不一致之处。领导者负责调和此类不一致之处。当关注者接收到AppendEntries RPC时,它也包含 term 和上一个日志条目的日志索引。如果这与关注者日志的最后一个条目不匹配,那么关注者将发送失败的响应。因此,领导者知道该特定节点的日志中存在不一致之处。

领导者通过跟踪每个关注者的 nextIndex 来解决日志不一致问题。当给定的跟随者的日志不一致时(即,它发送失败的响应时),则领导者递减 nextIndex 值,然后重试 AppendEntries RPC。此过程将继续进行,直到关注者日志与领导者一致为止。此外,每个节点还将本地日志保存在持久存储中。

安全

为了确保上述领导者选举和日志复制在所有条件下都能正常工作,我们需要为Raft算法增加一些安全条件。

选举限制-“领导的额外条件”

选举限制条件要求候选人的日志至少与其他节点一样最新。如果不是,则跟随者节点将不投票给候选者。 这意味着每个提交的条目都必须存在于这些服务器中的至少一个中。 如果候选人的日志至少与该多数中的任何其他日志一样最新,则它将保存所有已提交的条目。 因此, RequestVote  RPC 包含有关候选人日志的信息,如果投票者自己的日志比候选人的日志最新,则投票者将拒绝投票。

以前条款中的承诺条目-“承诺的附加条件”

如果同一领导者已成功复制了当前 term 的条目,则此条件是限制该领导者仅提交任何先前 term 的条目。当涉及分布式共识时,Raft 算法可提供以下保证。

  • 选举安全: 在给定的任期内最多可以选举一位领导人。
  • 领导者仅追加:领导者永远不会覆盖或删除其日志中的条目;它仅追加新条目。

  • 日志匹配:如果两个日志包含具有相同索引和 term 的条目,直到并包括给定索引的所有条目中的日志都是相同的。

  • 领导者完整性:如果在给定的期限内提交了日志条目,则该条目将出现在领导者的日志中,用于所有编号较高的 term

  • 状态机安全性:如果节点已将给定索引的日志条目应用于其状态机,则其他节点将永远不会为同一索引应用不同的日志条目。


- END -

本文为翻译文章,若侵权请联系后台删除

❤:在这里跟我一起学习技术、人生、原理、健身、摄影、生活等知识吧!

❤: 欢迎点个关注一起学习,让我们进步充实人生。