第 5 章 · 网络与分布式系统
“分布式系统的所有难题,都源于两个不确定性:没有全局时钟,不知道对方是死是活。“
本章覆盖的课程
| 编号 | 课程 | 本章的产出 |
|---|---|---|
| 046 | 网络编程实战 | 手写 epoll 网络框架(Go 版) |
| 053 | 分布式技术原理与算法解析 | 一致性模型、分布式事务、共识理论 |
| 112 | etcd 实战课 | Raft 完整实现(Go) |
章节结构
| 文档 | 内容 |
|---|---|
00-设计推演:从零造一个共识算法.md | ★ 必读:写三遍 → 多数派 → leader+日志 → term → 投票限制 → 一致性检查 → 提交条件,七次失败演进 |
01-网络编程:从 Socket 到 epoll.md | I/O 模型、epoll 原理、Reactor 模式、手写网络框架 |
02-分布式共识:Raft 完整实现.md | 一致性模型、Raft 选主/日志复制/安全性、完整 Go 实现 |
★ 先读
00-设计推演。 它不给你”Raft 有这些规则”,而是让你自己把每条规则从失败里推出来。特别是那句:“被多数派复制过” ≠ “已提交”——这是 Raft 实现里最常见的 bug, 只有亲手走完那个 5 节点、4 个 term 的崩溃时序,你才会真正记住。
学完这一章,你应该能
- 解释阻塞/非阻塞、同步/异步 I/O 的区别,以及 epoll 为什么高效
- 用 Go 手写一个基于 epoll 的网络框架(不用
net包) - 解释 LT 和 ET 模式的本质区别,以及为什么要配合非阻塞 I/O
- 解释线性一致性、顺序一致性、最终一致性的区别
- 用 Go 实现完整的 Raft(选主、日志复制、安全性、成员变更)
- 解释为什么 Raft 要限制”只能提交当前 term 的日志”
- 设计一个分布式锁、分布式事务
贯穿全章的核心洞察
洞察 1:并发的本质是”协调”
第 1 章我们讲过:单机并发的难题源于”CPU 会抢占”。
分布式系统里,难题源于:
① 没有全局时钟 → 无法判断两个事件的先后顺序
② 网络不可靠 → 消息可能丢失、重复、延迟、乱序
③ 节点可能失败 → 而且你无法区分"节点挂了"和"网络慢"
这三点导致:分布式系统里,“现在发生了什么”这个问题无法被精确回答。
所有的分布式算法(Raft、Paxos、2PC、向量时钟),本质上都是在用额外的通信和约束,重建一个”可以被推理的顺序”。
洞察 2:本地问题在分布式尺度的重演
你在第 1、3 章学过的很多东西,会在这一章以更大的尺度重现:
| 单机 | 分布式 |
|---|---|
| CPU 缓存一致性 (MESI) | 副本一致性(线性/顺序/最终) |
| 内存屏障 | 共识算法 |
| 锁 | 分布式锁 |
| 事务 (ACID) | 分布式事务 (2PC/TCC/Saga) |
| 顺序一致性(内存模型) | 顺序一致性(一致性模型) |
“让相关的东西物理上靠近” → “让计算靠近数据” “层次化缓存” → “CDN / 多级缓存” “用约束换性能” → “用一致性级别换可用性”
一个提醒
Raft 是这一章的重头戏。它不是”看懂就行”的东西——你必须自己写一遍,才能理解那些看起来莫名其妙的规则。
比如:“为什么 leader 只能提交当前 term 的日志?” ——看论文你可能觉得”哦,是为了安全”,但自己写一遍,构造出那个反例,你才会真正理解。
开始阅读:00-设计推演:从零造一个共识算法