Raft: Understandable Distributed Consensus
这篇交互式材料把 Raft 共识算法拆成可观察的选举、复制与恢复过程,让读者能沿着动画一步步理解一致性是如何形成的。问题背景原始页面先从单节点系统出发,说明只有在状态被复制到多个节点之后,一致性才真正变成一个复杂问题。它把 Raft 定义为一个用来决定权威状态、协调写入并在延迟或故障下继续工作的分布式一致性协议。核心机…
Raft:易于理解的分布式一致性 来源:The Secret Lives of Data - Raft 说明:本文是对 The Secret Lives of Data 原始交互页面的中文整理稿。它尽量忠实保留原页面的讲解顺序与核心示例,把动画中的逐步演示改写成可检索、可引用的 Markdown 文章。为什么需要分布式一致性 Raft 是一个用于实现分布式一致性的协议。原页面先从最简单的场景讲起:系统里只有一个节点,这个节点保存一个值。在这种情况下,达成一致几乎没有难度。客户端把值发给服务器,服务器写入状态,系统里“真相”只有一份。 真正的问题出现在系统扩展为多个节点之后。数据开始在集群里复制,系统就必须回答几个关键问题:到底谁负责接收写入、其他节点如何学习新状态、什么时候可以认为一次修改已经可靠生效、当节点失联或消息延迟时又该如何恢复一致。这正是 Raft 要解决的分布式一致性问题。协议总览 Raft 把集群中的节点组织为三种状态:Follower(跟随者)Candidate(候选者)Leader(领导者) 所有节点一开始都是跟随者。如果某个跟随者在一段时间内没有收到领导者的消息,它就会变成候选者。候选者向其他节点请求投票;一旦拿到多数票,它就成为新的领导者。 当领导者出现后,系统中的所有变更都要先经过它。客户端把命令发给领导者,领导者先把命令追加到自己的日志中,再把这条日志复制给跟随者。只有当多数节点都写入了这条日志,领导者才会把它标记为已提交,并通知其他节点同步提交状态。到这一步,整个集群才算对新的系统状态达成了一致。 原页面正是围绕两条主线来解释 Raft:领导者选举日志复制用单节点例子建立直觉 交互式引导部分先用单节点系统建立直觉。你可以把这个节点理解为一个只保存单个值的数据库服务器。客户端发送一个新值,节点更新自己的状态,于是一致性问题几乎不存在,因为只有一个位置负责保存真实状态。 当同样的问题扩展到多个节点时,难点马上就出现了:到底由哪个节点接收写请求?其他节点如何得知新的值?什么时候一条变更才算真正可靠?如果不同节点对“最新状态”有不同看法,该怎么办? Raft 的答案是:先选出一个领导者,再围绕一份有序日志来复制状态。领导者选举 交互页面先介绍了控制选举行为的两个超时参数:选举超时(election timeout)心跳超时(heartbeat timeout) 选举超时表示一个跟随者要等待多久,才会在没有听到领导者消息时尝试成为候选者。原页面给出的范围是 150ms 到 300ms,并强调这个时间是随机化的。随机化的目的,是降低多个跟随者同时发起选举、相互冲突的概率。 当某个跟随者超时后,它会转换为候选者,开始一个新的任期(term),并先给自己投票,然后向其他节点发送 Request Vote 请求。如果接收方在这个任期里还没有投过票,它就可以把票投给这个候选者,同时重置自己的选举超时。 一旦候选者拿到多数票,它就会成为领导者。新的领导者随后开始持续向跟随者发送 Append Entries 消息。即使当前没有新的客户端命令,这些消息也会作为心跳存在,让跟随者知道领导者仍然在线。 原页面接着演示了重新选举的过程。如果当前领导者停止工作,跟随者最终会收不到心跳。某个跟随者会先超时、变成候选者、赢得多数票,然后在更高任期里成为新的领导者。 页面还展示了“分票”场景。如果两个节点几乎同时在同一个任期内变成候选者,它们都可能拿到一部分选票,却谁也达不到多数。这时该任期里不会产生领导者,节点们会等待下一轮选举,最终由某个候选者获得多数票。也正因为必须得到多数支持,Raft 才能保证同一任期内最多只有一个领导者。日志复制 选出领导者之后,所有更新都会经过它。 原页面用 SET 5 这样的客户端命令来演示复制过程:客户端把变更发送给领导者。领导者先把命令追加到自己的日志中。领导者通过 Append Entries 把这条日志发送给跟随者。当多数节点确认写入后,领导者把该条目标记为已提交。领导者通知跟随者这条日志已经提交。集群各节点的可见状态收敛为同一个值。 这里有个关键点:未提交的日志条目不会立刻改变节点对外可见的状态。只有当多数节点都已经写下这条日志,它才算真正生效。原页面随后又用 ADD 2 这个命令,把系统值从 5 推进到 7,进一步强调“复制到多数并提交”才是状态变化真正成立的时刻。网络分区下的一致性 这个交互页面最有教学价值的部分之一,是网络分区示例。页面把集群切成两半,让 A、B 与 C、D、E 之间失去连通。 因为通信被切断,分区两边可能会暂时出现处于不同任期的两个领导者。但 Raft 依然能保护已经提交的一致性状态:少数派一侧的领导者无法把日志复制到多数节点因而它新增的日志条目只能停留在“未提交”状态多…
正在初始化 WebAssembly 引擎…
首次编译原生模块可能需要数秒
就绪后,页面交互将以接近原生的速度运行