<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>一致性算法 on 牛哥聊技术</title><link>https://www.lingcoder.com/tags/%E4%B8%80%E8%87%B4%E6%80%A7%E7%AE%97%E6%B3%95/</link><description>Recent content in 一致性算法 on 牛哥聊技术</description><generator>Hugo -- gohugo.io</generator><language>zh</language><lastBuildDate>Sun, 15 Dec 2024 15:30:00 +0800</lastBuildDate><atom:link href="https://www.lingcoder.com/tags/%E4%B8%80%E8%87%B4%E6%80%A7%E7%AE%97%E6%B3%95/index.xml" rel="self" type="application/rss+xml"/><item><title>浅谈 Raft：让分布式一致性变可理解的算法</title><link>https://www.lingcoder.com/p/raft-consensus-explained/</link><pubDate>Sun, 15 Dec 2024 15:30:00 +0800</pubDate><guid>https://www.lingcoder.com/p/raft-consensus-explained/</guid><description>&lt;img src="https://www.lingcoder.com/p/raft-consensus-explained/cover.svg" alt="Featured image of post 浅谈 Raft：让分布式一致性变可理解的算法" /&gt;&lt;h2 id="写在前面"&gt;&lt;a href="#%e5%86%99%e5%9c%a8%e5%89%8d%e9%9d%a2" class="header-anchor"&gt;&lt;/a&gt;写在前面
&lt;/h2&gt;&lt;p&gt;分布式系统里&amp;quot;多个节点对一件事达成一致&amp;quot;听起来简单，做对极难——这就是**共识算法（Consensus）**要解决的问题。&lt;/p&gt;
&lt;p&gt;最经典的共识算法是 &lt;strong&gt;Paxos&lt;/strong&gt;——Lamport 1998 年的论文。但 Paxos 论文有个臭名昭著的问题：&lt;strong&gt;没人看得懂&lt;/strong&gt;。Lamport 后来又写了&amp;quot;
Paxos Made Simple&amp;quot;试图解释——还是难懂。&lt;/p&gt;
&lt;p&gt;2014 年 Stanford 的 Diego Ongaro 和 John Ousterhout 提出了 &lt;strong&gt;Raft 算法&lt;/strong&gt;——明确目标是&amp;quot;&lt;strong&gt;可理解性优先&lt;/strong&gt;&amp;quot;。论文标题就是 &lt;em&gt;In
Search of an Understandable Consensus Algorithm&lt;/em&gt;。&lt;/p&gt;
&lt;p&gt;Raft 现在是工业界事实标准——&lt;strong&gt;etcd、Consul、TiKV、CockroachDB、HashiCorp 全家桶&lt;/strong&gt;都在用。本文用直觉的方式把 Raft
讲清楚——不写公式，但讲清核心机制和工程意义。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="一共识算法在解决什么问题"&gt;&lt;a href="#%e4%b8%80%e5%85%b1%e8%af%86%e7%ae%97%e6%b3%95%e5%9c%a8%e8%a7%a3%e5%86%b3%e4%bb%80%e4%b9%88%e9%97%ae%e9%a2%98" class="header-anchor"&gt;&lt;/a&gt;一、共识算法在解决什么问题
&lt;/h2&gt;&lt;p&gt;设想 5 台机器要一起维护一份日志：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Machine 1: [A, B, C, D]
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Machine 2: [A, B, C, ?]
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Machine 3: [A, B, C, D, E]
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Machine 4: [A, B, ?, ?]
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Machine 5: [A, B, C, D]
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;某些机器宕机、网络分区、消息延迟——&lt;strong&gt;怎么保证所有活着的机器最终都看到同一份日志？&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;共识算法要保证：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Safety（安全性）&lt;/strong&gt;：即使发生故障，所有节点的状态不会冲突&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Liveness（活性）&lt;/strong&gt;：只要多数节点存活，系统能继续工作&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Consistency（一致性）&lt;/strong&gt;：相同输入序列产生相同输出&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Raft 用三个核心机制实现这些性质——&lt;strong&gt;领导选举、日志复制、安全性&lt;/strong&gt;。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="二raft-的角色"&gt;&lt;a href="#%e4%ba%8craft-%e7%9a%84%e8%a7%92%e8%89%b2" class="header-anchor"&gt;&lt;/a&gt;二、Raft 的角色
&lt;/h2&gt;&lt;p&gt;集群里每个节点处于三种状态之一：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Leader&lt;/strong&gt;：唯一的&amp;quot;指挥官&amp;quot;，处理所有客户端请求&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Follower&lt;/strong&gt;：被动响应 Leader 和 Candidate 的消息&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Candidate&lt;/strong&gt;：选举期间的临时角色&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="mermaid" style="visibility:hidden"&gt;flowchart LR
 Follower --&gt;|超时未收到心跳| Candidate
 Candidate --&gt;|获得多数票| Leader
 Candidate --&gt;|发现已有 Leader| Follower
 Leader --&gt;|发现更高 term| Follower&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;任何时刻只有一个 Leader&lt;/strong&gt;——这是 Raft 简化的关键。所有写入都通过 Leader——Leader 把变更复制到 Followers——Follower
投票确认——Leader 提交并通知所有人。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="三领导选举"&gt;&lt;a href="#%e4%b8%89%e9%a2%86%e5%af%bc%e9%80%89%e4%b8%be" class="header-anchor"&gt;&lt;/a&gt;三、领导选举
&lt;/h2&gt;&lt;p&gt;集群启动时所有节点都是 Follower。每个节点有一个&lt;strong&gt;随机选举超时&lt;/strong&gt;（150-300ms）：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Follower 在超时内没收到 Leader 心跳 → 转为 Candidate&lt;/li&gt;
&lt;li&gt;Candidate 给自己投一票，向其他节点发送&amp;quot;选我&amp;quot;请求&lt;/li&gt;
&lt;li&gt;其他节点收到后：
&lt;ul&gt;
&lt;li&gt;如果当前 term 没投过票 → 投票给它&lt;/li&gt;
&lt;li&gt;如果已投过票 → 拒绝&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Candidate 收到&lt;strong&gt;多数票（n/2+1）&lt;/strong&gt;→ 成为 Leader&lt;/li&gt;
&lt;li&gt;新 Leader 立刻发心跳，宣告自己存在&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class="mermaid" style="visibility:hidden"&gt;sequenceDiagram
 Note over Node1,Node5: 所有 Follower
 Node1--&gt;&gt;Node1: 选举超时
 Node1-&gt;&gt;Node2: RequestVote (term=1)
 Node1-&gt;&gt;Node3: RequestVote
 Node1-&gt;&gt;Node4: RequestVote
 Node1-&gt;&gt;Node5: RequestVote
 Node2--&gt;&gt;Node1: 投票 ✓
 Node3--&gt;&gt;Node1: 投票 ✓
 Note over Node1: 收到 3/5 票
 Note over Node1: 成为 Leader
 Node1-&gt;&gt;Node2: 心跳
 Node1-&gt;&gt;Node3: 心跳&lt;/pre&gt;&lt;h3 id="为什么要随机超时"&gt;&lt;a href="#%e4%b8%ba%e4%bb%80%e4%b9%88%e8%a6%81%e9%9a%8f%e6%9c%ba%e8%b6%85%e6%97%b6" class="header-anchor"&gt;&lt;/a&gt;为什么要随机超时
&lt;/h3&gt;&lt;p&gt;如果所有节点超时一致——&lt;strong&gt;所有节点同时变 Candidate，互相投票冲突，没人能赢&lt;/strong&gt;。随机化让某个节点先到超时点——它最早开始拉票，更容易胜出。&lt;/p&gt;
&lt;h3 id="term-概念"&gt;&lt;a href="#term-%e6%a6%82%e5%bf%b5" class="header-anchor"&gt;&lt;/a&gt;Term 概念
&lt;/h3&gt;&lt;p&gt;Raft 把时间分成&amp;quot;任期&amp;quot;（Term）——每次选举触发新的 term。Term 是单调递增的整数。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Leader 每次发心跳带上自己的 term&lt;/li&gt;
&lt;li&gt;Follower 收到更高 term → 降级、跟随新 Leader&lt;/li&gt;
&lt;li&gt;旧 Leader 网络恢复后看到更高 term → 自动退位&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Term 解决了&amp;quot;脑裂后旧 Leader 还以为自己是 Leader&amp;quot;的问题&lt;/strong&gt;——所有响应都校验 term，更高 term 自动获胜。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="四日志复制"&gt;&lt;a href="#%e5%9b%9b%e6%97%a5%e5%bf%97%e5%a4%8d%e5%88%b6" class="header-anchor"&gt;&lt;/a&gt;四、日志复制
&lt;/h2&gt;&lt;p&gt;Leader 收到客户端写请求后：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;写入自己的日志&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;并行发给所有 Follower&lt;/strong&gt;（AppendEntries RPC）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;多数 Follower 确认收到&lt;/strong&gt; → 提交（commit）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;下次心跳通知 Follower 提交&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;提交后应用到状态机，回复客户端&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class="mermaid" style="visibility:hidden"&gt;sequenceDiagram
 Client-&gt;&gt;Leader: write x=5
 Leader-&gt;&gt;Leader: append log
 par
 Leader-&gt;&gt;Follower1: AppendEntries
 Leader-&gt;&gt;Follower2: AppendEntries
 Leader-&gt;&gt;Follower3: AppendEntries
 Leader-&gt;&gt;Follower4: AppendEntries
 end
 Follower1--&gt;&gt;Leader: ack
 Follower2--&gt;&gt;Leader: ack
 Follower3--&gt;&gt;Leader: ack
 Note over Leader: 收到 3/5 ack
 Leader-&gt;&gt;Leader: commit
 Leader--&gt;&gt;Client: ok
 Leader-&gt;&gt;Follower1: 下次心跳通知 commit&lt;/pre&gt;&lt;h3 id="日志一致性"&gt;&lt;a href="#%e6%97%a5%e5%bf%97%e4%b8%80%e8%87%b4%e6%80%a7" class="header-anchor"&gt;&lt;/a&gt;日志一致性
&lt;/h3&gt;&lt;p&gt;每条日志带上 &lt;code&gt;(term, index)&lt;/code&gt;——Follower 收到 AppendEntries 时检查：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;上一条日志的 (term, index) 和我本地的对得上吗？&lt;/li&gt;
&lt;li&gt;对得上 → 追加新日志&lt;/li&gt;
&lt;li&gt;对不上 → 拒绝，让 Leader 退一格再发&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Leader 维护每个 Follower 的 &lt;code&gt;nextIndex&lt;/code&gt;——发现 Follower 跟不上时&lt;strong&gt;逐步回退、重发&lt;/strong&gt;，直到对齐。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="五安全性约束"&gt;&lt;a href="#%e4%ba%94%e5%ae%89%e5%85%a8%e6%80%a7%e7%ba%a6%e6%9d%9f" class="header-anchor"&gt;&lt;/a&gt;五、安全性约束
&lt;/h2&gt;&lt;p&gt;光有选举和复制不够——&lt;strong&gt;必须保证已提交的日志永远不丢&lt;/strong&gt;。Raft 通过几个约束实现：&lt;/p&gt;
&lt;h3 id="1-选举限制只有日志最新的节点能赢"&gt;&lt;a href="#1-%e9%80%89%e4%b8%be%e9%99%90%e5%88%b6%e5%8f%aa%e6%9c%89%e6%97%a5%e5%bf%97%e6%9c%80%e6%96%b0%e7%9a%84%e8%8a%82%e7%82%b9%e8%83%bd%e8%b5%a2" class="header-anchor"&gt;&lt;/a&gt;1. 选举限制：只有&amp;quot;日志最新&amp;quot;的节点能赢
&lt;/h3&gt;&lt;p&gt;Candidate 拉票时附带&lt;strong&gt;自己最后一条日志的 (term, index)&lt;/strong&gt;。Follower 只投票给&amp;quot;日志比自己新或一样新&amp;quot;的 Candidate。&lt;/p&gt;
&lt;p&gt;这保证&lt;strong&gt;新 Leader 一定包含所有已提交的日志&lt;/strong&gt;——不会有&amp;quot;新 Leader 上任后丢掉之前已提交的事&amp;quot;。&lt;/p&gt;
&lt;h3 id="2-提交限制只能提交当前-term-的日志"&gt;&lt;a href="#2-%e6%8f%90%e4%ba%a4%e9%99%90%e5%88%b6%e5%8f%aa%e8%83%bd%e6%8f%90%e4%ba%a4%e5%bd%93%e5%89%8d-term-%e7%9a%84%e6%97%a5%e5%bf%97" class="header-anchor"&gt;&lt;/a&gt;2. 提交限制：只能提交当前 term 的日志
&lt;/h3&gt;&lt;p&gt;Leader 不能直接提交&amp;quot;上一个 term 的日志&amp;quot;——只能等当前 term 有日志被多数复制后，&lt;strong&gt;带着把之前的日志一起提交&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;这避免了一个微妙的 bug——Lamport 的 Paxos 也有类似机制，但 Raft 把它讲得更清楚。&lt;/p&gt;
&lt;h3 id="3-appendentries-一致性检查"&gt;&lt;a href="#3-appendentries-%e4%b8%80%e8%87%b4%e6%80%a7%e6%a3%80%e6%9f%a5" class="header-anchor"&gt;&lt;/a&gt;3. AppendEntries 一致性检查
&lt;/h3&gt;&lt;p&gt;每次发日志都带上前一条日志的 (term, index)——Follower 检查匹配后才追加。这是一种&lt;strong&gt;简单粗暴但有效&lt;/strong&gt;的对齐方式。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="六几个常见问题"&gt;&lt;a href="#%e5%85%ad%e5%87%a0%e4%b8%aa%e5%b8%b8%e8%a7%81%e9%97%ae%e9%a2%98" class="header-anchor"&gt;&lt;/a&gt;六、几个常见问题
&lt;/h2&gt;&lt;h3 id="1-网络分区怎么办"&gt;&lt;a href="#1-%e7%bd%91%e7%bb%9c%e5%88%86%e5%8c%ba%e6%80%8e%e4%b9%88%e5%8a%9e" class="header-anchor"&gt;&lt;/a&gt;1. 网络分区怎么办
&lt;/h3&gt;&lt;p&gt;5 节点集群被分成 [3, 2]：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;3 节点的子集仍可选举出 Leader、继续对外服务（多数派）&lt;/li&gt;
&lt;li&gt;2 节点子集无法选出新 Leader、只能等待&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;分区恢复后——2 节点子集发现更高 term，自动跟随大集群的 Leader。&lt;strong&gt;未提交的事务被覆盖&lt;/strong&gt;。&lt;/p&gt;
&lt;h3 id="2-leader-故障"&gt;&lt;a href="#2-leader-%e6%95%85%e9%9a%9c" class="header-anchor"&gt;&lt;/a&gt;2. Leader 故障
&lt;/h3&gt;&lt;p&gt;Leader 宕机后心跳停止——某个 Follower 选举超时变 Candidate——选出新 Leader——继续工作。&lt;strong&gt;通常 1-2 秒内完成切换&lt;/strong&gt;。&lt;/p&gt;
&lt;h3 id="3-客户端读"&gt;&lt;a href="#3-%e5%ae%a2%e6%88%b7%e7%ab%af%e8%af%bb" class="header-anchor"&gt;&lt;/a&gt;3. 客户端读
&lt;/h3&gt;&lt;p&gt;朴素做法：所有读都走 Leader——保证强一致，但 Leader 压力大。&lt;/p&gt;
&lt;p&gt;优化方案：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;ReadIndex&lt;/strong&gt;：读时让 Leader 确认自己仍是 Leader（一次心跳），然后本地读&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Lease Read&lt;/strong&gt;：Leader 持有&amp;quot;租约&amp;quot;，租约期内本地读&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Follower Read&lt;/strong&gt;：允许从 Follower 读（弱一致，但快）&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="4-集群成员变更"&gt;&lt;a href="#4-%e9%9b%86%e7%be%a4%e6%88%90%e5%91%98%e5%8f%98%e6%9b%b4" class="header-anchor"&gt;&lt;/a&gt;4. 集群成员变更
&lt;/h3&gt;&lt;p&gt;加节点 / 减节点这种&amp;quot;在运行中变更集群配置&amp;quot;——Raft 用&lt;strong&gt;两阶段共识&lt;/strong&gt;（Joint Consensus）：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;先达成&amp;quot;新旧配置共存&amp;quot;的共识&lt;/li&gt;
&lt;li&gt;再切到纯新配置&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;避免了&amp;quot;新旧多数派同时存在导致两个 Leader&amp;quot;的脑裂。&lt;/p&gt;
&lt;h3 id="5-日志压缩"&gt;&lt;a href="#5-%e6%97%a5%e5%bf%97%e5%8e%8b%e7%bc%a9" class="header-anchor"&gt;&lt;/a&gt;5. 日志压缩
&lt;/h3&gt;&lt;p&gt;日志一直涨会爆磁盘——Raft 用&lt;strong&gt;快照（Snapshot）&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;周期性把状态机全量存盘&lt;/li&gt;
&lt;li&gt;旧日志可以删除&lt;/li&gt;
&lt;li&gt;新加入的节点先拉快照，再追日志&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="七raft-的工业实现"&gt;&lt;a href="#%e4%b8%83raft-%e7%9a%84%e5%b7%a5%e4%b8%9a%e5%ae%9e%e7%8e%b0" class="header-anchor"&gt;&lt;/a&gt;七、Raft 的工业实现
&lt;/h2&gt;&lt;h3 id="etcd"&gt;&lt;a href="#etcd" class="header-anchor"&gt;&lt;/a&gt;etcd
&lt;/h3&gt;&lt;p&gt;Kubernetes 的元数据存储——5 节点 Raft 集群最常见。&lt;strong&gt;高可用 + 强一致&lt;/strong&gt;——但写性能不高（每次都要多数派 ack）。&lt;/p&gt;
&lt;h3 id="consul"&gt;&lt;a href="#consul" class="header-anchor"&gt;&lt;/a&gt;Consul
&lt;/h3&gt;&lt;p&gt;HashiCorp 的服务发现——同样 5 节点 Raft。&lt;/p&gt;
&lt;h3 id="tikv"&gt;&lt;a href="#tikv" class="header-anchor"&gt;&lt;/a&gt;TiKV
&lt;/h3&gt;&lt;p&gt;PingCAP 的分布式 KV——&lt;strong&gt;每个数据 region 独立 Raft&lt;/strong&gt;——上千个 Raft 组并行。&lt;/p&gt;
&lt;h3 id="cockroachdb"&gt;&lt;a href="#cockroachdb" class="header-anchor"&gt;&lt;/a&gt;CockroachDB
&lt;/h3&gt;&lt;p&gt;SQL 数据库底层用 Raft 复制每个 range。&lt;/p&gt;
&lt;h3 id="apache-ratis"&gt;&lt;a href="#apache-ratis" class="header-anchor"&gt;&lt;/a&gt;Apache Ratis
&lt;/h3&gt;&lt;p&gt;通用 Raft 库（Java）——OZone、Apache Iceberg 等用它。&lt;/p&gt;
&lt;h3 id="mit-6824-的-lab"&gt;&lt;a href="#mit-6824-%e7%9a%84-lab" class="header-anchor"&gt;&lt;/a&gt;MIT 6.824 的 Lab
&lt;/h3&gt;&lt;p&gt;学 Raft 最好的方式是&lt;strong&gt;自己实现一遍&lt;/strong&gt;——MIT 6.824 的 Lab 2A/2B/2C 就是手写 Raft。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="八raft-vs-paxos-vs-multi-paxos"&gt;&lt;a href="#%e5%85%abraft-vs-paxos-vs-multi-paxos" class="header-anchor"&gt;&lt;/a&gt;八、Raft vs Paxos vs Multi-Paxos
&lt;/h2&gt;&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th style="text-align: left"&gt;&lt;/th&gt;
 &lt;th style="text-align: left"&gt;Paxos&lt;/th&gt;
 &lt;th style="text-align: left"&gt;Multi-Paxos&lt;/th&gt;
 &lt;th style="text-align: left"&gt;Raft&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td style="text-align: left"&gt;出处&lt;/td&gt;
 &lt;td style="text-align: left"&gt;Lamport 1998&lt;/td&gt;
 &lt;td style="text-align: left"&gt;同上扩展&lt;/td&gt;
 &lt;td style="text-align: left"&gt;Ongaro 2014&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td style="text-align: left"&gt;角色&lt;/td&gt;
 &lt;td style="text-align: left"&gt;Proposer/Acceptor/Learner&lt;/td&gt;
 &lt;td style="text-align: left"&gt;同上&lt;/td&gt;
 &lt;td style="text-align: left"&gt;Leader/Follower/Candidate&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td style="text-align: left"&gt;强 Leader&lt;/td&gt;
 &lt;td style="text-align: left"&gt;✗&lt;/td&gt;
 &lt;td style="text-align: left"&gt;✓&lt;/td&gt;
 &lt;td style="text-align: left"&gt;✓&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td style="text-align: left"&gt;可理解性&lt;/td&gt;
 &lt;td style="text-align: left"&gt;低&lt;/td&gt;
 &lt;td style="text-align: left"&gt;中&lt;/td&gt;
 &lt;td style="text-align: left"&gt;&lt;strong&gt;高&lt;/strong&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td style="text-align: left"&gt;工业实现&lt;/td&gt;
 &lt;td style="text-align: left"&gt;Chubby 早期文献描述&lt;/td&gt;
 &lt;td style="text-align: left"&gt;Chubby / Spanner / Megastore&lt;/td&gt;
 &lt;td style="text-align: left"&gt;etcd / Consul / TiKV / 几乎所有新系统&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;

 &lt;blockquote&gt;
 &lt;p&gt;&lt;strong&gt;关于 ZooKeeper&lt;/strong&gt;：ZooKeeper 用的是 &lt;strong&gt;ZAB（ZooKeeper Atomic Broadcast）&lt;/strong&gt;——不是 Multi-Paxos，而是一种 Paxos 变体，针对&amp;quot;
主备复制 + 严格按序广播&amp;quot;做了简化。ZAB 和 Raft 的设计哲学接近（强 Leader + 心跳 + 单调递增的 epoch / term），但出现得更早，是
ZK 自家的方案。&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;p&gt;Raft 在功能上和 Multi-Paxos 等价——但&lt;strong&gt;可理解性、可实现性、可调试性&lt;/strong&gt;都强很多。这就是它后来居上的核心原因。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="九什么时候用-raft什么时候不用"&gt;&lt;a href="#%e4%b9%9d%e4%bb%80%e4%b9%88%e6%97%b6%e5%80%99%e7%94%a8-raft%e4%bb%80%e4%b9%88%e6%97%b6%e5%80%99%e4%b8%8d%e7%94%a8" class="header-anchor"&gt;&lt;/a&gt;九、什么时候用 Raft、什么时候不用
&lt;/h2&gt;&lt;p&gt;✅ 适合：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;需要&lt;strong&gt;强一致性&lt;/strong&gt;的元数据存储（K8s 配置、服务发现）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;数据库的元数据复制&lt;/strong&gt;（schema、租约）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;小规模集群&lt;/strong&gt;（3-7 节点）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;写入不频繁但要绝对可靠&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;❌ 不适合：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;大规模数据复制&lt;/strong&gt;（百 GB 数据）——延迟高&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;极高写入吞吐场景&lt;/strong&gt;——多数派 ack 是瓶颈&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;跨数据中心&lt;/strong&gt;——网络延迟让心跳和投票变得脆弱&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;AP 系统&lt;/strong&gt;（如 Cassandra）——选 P + A 而不是 C，根本不需要共识&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;最低要 3 节点（容忍 1 个故障）、推荐 5 节点（容忍 2 个）——&lt;strong&gt;永远不要 1 节点 Raft&lt;/strong&gt;，那等于没用。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="十对工程的启发"&gt;&lt;a href="#%e5%8d%81%e5%af%b9%e5%b7%a5%e7%a8%8b%e7%9a%84%e5%90%af%e5%8f%91" class="header-anchor"&gt;&lt;/a&gt;十、对工程的启发
&lt;/h2&gt;&lt;p&gt;Raft 不只是&amp;quot;一个算法&amp;quot;——它示范了几个值得借鉴的工程哲学：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;可理解性是设计目标&lt;/strong&gt;——不只是&amp;quot;能 work&amp;quot;，要&amp;quot;能讲清&amp;quot;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;强 Leader 简化系统&lt;/strong&gt;——比起完全对称的 Paxos，单 Leader 让推理更容易&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;机制分离&lt;/strong&gt;：选举、复制、安全性各自独立讲清楚&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;拒绝复杂特性&lt;/strong&gt;：Raft 的论文明确说&amp;quot;拒绝任何不必要的复杂&amp;quot;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;设计任何分布式系统时——&lt;strong&gt;理解 Raft 都是入门必修课&lt;/strong&gt;。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="小结"&gt;&lt;a href="#%e5%b0%8f%e7%bb%93" class="header-anchor"&gt;&lt;/a&gt;小结
&lt;/h2&gt;&lt;p&gt;把全文压一句：&lt;/p&gt;

 &lt;blockquote&gt;
 &lt;p&gt;**Raft 用『强 Leader + 多数派复制 + 严格安全约束』把分布式一致性讲得像故事——可理解性是它最大的成就，可工业化是它的最大遗产。
**&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;p&gt;学习路径推荐：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;读 Raft 论文&lt;/strong&gt;：&lt;a class="link" href="https://raft.github.io" target="_blank" rel="noopener"
 &gt;raft.github.io&lt;/a&gt;（强烈推荐）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;看可视化&lt;/strong&gt;：&lt;a class="link" href="http://thesecretlivesofdata.com/raft/" target="_blank" rel="noopener"
 &gt;The Secret Lives of Data&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;手写实现&lt;/strong&gt;：MIT 6.824 Lab 2&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;用一遍 etcd / Consul&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;掌握 Raft 后再看 ZooKeeper、ZAB、Spanner 的 Multi-Paxos——能立刻看出它们解决问题的相同与不同。&lt;/p&gt;</description></item></channel></rss>