分布式系统怎么“选主“?Raft 共识一次讲清

分布式系统怎么"选主"?Raft 共识一次讲清

一个分布式系统有 5 个节点,主节点突然挂了,谁来当新老大?如果两个节点同时宣称自己是老大,系统就"脑裂"了。Raft 是今天最流行的答案------它把"选主"变成一套清晰可验证的规则。今天讲透它。

一、为什么"选主"这么难?

分布式系统的节点通过网络连接,网络会断、节点会挂。难点在于:你无法区分"对方挂了"和"网络慢了"

  • 主节点可能真的崩溃了
  • 也可能只是网络分区,它还在另一头正常工作

如果贸然选新主,可能出现两个"主"同时发号施令------脑裂,数据就乱了。

二、Raft 的设计哲学:可理解性优先

Paxos 是第一个共识算法,但以"难以理解、更难实现"著称。Raft 的目标是把共识拆成清晰子问题,每个都给出单一明确的做法:

  1. 领导人选举:怎么选老大
  2. 日志复制:老大怎么把数据同步给大家
  3. 安全性:怎么保证不乱

核心结构:平时一个 Leader,出事再选 Leader。所有写请求都经过 Leader,Follower 被动跟随。

三、任期(term):系统的"逻辑时钟"

Raft 引入全局单调递增的任期号------可以理解为"第几届政府",每届至多有一个 Leader

任期的作用:

  • 排序:所有消息带任期,见到更高任期立刻"认怂"(降级为 Follower)
  • 防脑裂:旧 Leader"复活"想发号施令,它的旧任期消息会被拒绝
  • 选举边界:每轮选举绑定唯一任期

四、选举流程:六步走

每个节点有三种角色:Follower(默认)、Candidate(候选人)、Leader(老大)。

  1. Leader 崩溃,停止发送心跳
  2. 各 Follower 有随机的选举超时(150-300ms),最先超时的那个把任期 +1,变成 Candidate,给自己投一票
  3. Candidate 向其他节点发 RequestVote 拉票
  4. 收到请求且任期合法的 Follower 投票,并重置自己的超时
  5. 拿到多数派选票(3/5)→ 成为 Leader,马上发心跳宣示主权
  6. 若超时未决出(平票)→ 任期再 +1,重新随机超时再选

随机超时是关键:如果所有节点同时超时同时竞选,会无限平票------随机化保证"总有人先醒"。

五、代码演示:模拟一次选举

python 复制代码
import random

def raft_election(nodes=5, timeout_range=(150, 300)):
    timeouts = {i: random.uniform(*timeout_range) for i in range(nodes)}
    leader = min(timeouts, key=timeouts.get)   # 最先超时者发起选举
    votes = [leader]                            # 投自己
    for i in range(nodes):
        if i != leader and random.random() < 0.9:
            votes.append(i)                     # 其他节点投票
    return leader, len(votes), votes

random.seed(7)
leader, nvotes, voters = raft_election()
print(f"5 节点选举: 节点{leader} 最先超时发起选举, 获得 {nvotes}/5 票")
print(f"投票者: {voters}")
print(f"结果: {'成为 Leader' if nvotes >= 3 else '选票不足, 重选'}")

运行输出(随机种子固定,结果可复现):

复制代码
5 节点选举: 节点3 最先超时发起选举, 获得 5/5 票
投票者: [3, 0, 1, 2, 4]
结果: 成为 Leader

随机超时让节点 3"先醒",拿到全部 5 票当选。如果它只拿到 2 票,任期 +1 重新竞选------多数派原则保证任何时刻最多一个合法 Leader

六、避坑清单

  1. 多数派不是"超过一半在线" :是超过全部节点的一半(3/5),少数节点无法独自选主------这就是防脑裂的数学保证
  2. 随机超时别省:固定超时会同时竞选、无限平票
  3. 任期单调递增:节点收到更高任期必须认怂降级,这是收敛的关键
  4. 日志复制和选举是一体:新 Leader 必须先补齐日志才能开始服务(安全性的核心)
  5. 别自己实现 Raft:用 etcd/Raft 库,共识算法的边角(成员变更、快照)极其容易出错

七、想系统学分布式系统?

本文精选自 ima 知识号【Kruptos】《分布式系统详解》订阅库(第 029 期 Raft 选举任期与投票、第 030 期 Raft 日志复制、第 031 期 Raft 安全性与成员变更等 100 期系统教程,从时钟、一致性模型、RPC、共识算法到分布式存储,每期配可运行 Python 代码)。

📚 完整系列 100 期 + 配套代码,已在 ima 知识号发布

本文只是系列的一个切片。完整系列(100 期系统教程 + 每期可运行代码)在 ima 知识号【Kruptos】持续更新中:

  • 🗂 67+ 技术知识库:信号与系统、SDR 软件无线电、数字信号处理、操作系统、AI Agent、大模型微调......几乎覆盖全部软硬件技术栈
  • 🧠 8 款 AI 技能:系列生产、知识库管理、CMMI 受管开发、自进化 Agent 等,已在 ima 技能广场上架,即装即用
  • ✅ 全部免费订阅,后续更新自动推送

🔍 订阅方式:打开 ima(腾讯智能工作台)→ 搜索「Kruptos」→ 一键订阅。或在 ima 内直接搜索《分布式系统详解》等知识库名称。

💬 你线上遇到过"选主"相关的事故吗?评论区聊聊------想看 Paxos vs Raft 还是日志复制,点赞高的安排。


作者:Kruptos(西电毕业,13 年无线通信/DSP/嵌入式科研)|原创内容,转载注明出处

相关推荐
吴声子夜歌1 小时前
ApacheCommons——commons-cli(命令行参数解析)
java·开发语言·apache
benchmark_cc2 小时前
REST API 和 Python SDK 应该怎么选?量化交易数据接口选型实战
开发语言·python·数据分析·pandas·量化交易·股票数据·quantdash
王的宝库2 小时前
Go 项目结构:从单文件到标准工程布局
开发语言·后端·golang
Tairitsu_H2 小时前
[C++] 深入理解红黑树:封装set与map
开发语言·c++·set·map·红黑树·模拟实现
泡海椒2 小时前
JQuick-Curl 性能分析:并发场景下的性能表现与调优,第三方接口调用不只要快写也要稳跑
java·开发语言·okhttp
小智老师PMP2 小时前
2026深度解析|PMP第八版与NPDP核心侧重点本质区别(管理类证书怎么选)
开发语言·分布式·算法·职场和发展·产品经理
江畔柳前堤4 小时前
前台·中台·后台:2026年AI原生时代的架构全景图
开发语言·人工智能·算法·机器学习·架构·scala·ai-native
Figo_Cheung4 小时前
Figo基于RNC理论的宇宙演化第七纪元猜想
开发语言·php
会周易的程序员4 小时前
5Draft(五帝)测试报告
服务器·c++·分布式·raft·共识算法·共识·算力服务器