范围、取舍与不重复清单
1 本书的问题边界
本书讨论数据面(data plane):一次请求从离开客户端到落盘/返回之间,数据怎么走、状态怎么变、失败怎么处理。控制面(control plane)只在必要处出现,因为控制面的错误最终也会以数据面的形式暴露——例如 etcd 选举抖动会变成 apiserver 的 5xx,Kubernetes 的滚动发布会被误读成「服务变慢」。
| 属于本书 | 不属于本书 |
|---|---|
| RPC 的超时、重试、幂等、背压 | HTTP/2 帧格式、TLS 握手、DNS 解析细节 |
| 主从/多主/无主复制、quorum、读修复 | TCP 拥塞控制、epoll 事件循环实现 |
| 线性/顺序/因果/最终一致性的定义与判定 | CAP 口号与「三者选二」的营销叙事 |
| Paxos、Raft、选举、日志提交、线性一致读 | 分布式系统的形式化证明全集 |
| ACID、隔离级别、MVCC、2PC/TCC/Saga | 某个数据库的全部 SQL 语法 |
| 队列/日志、投递语义、消费者组、CDC | Kafka 的每个配置项逐条解释 |
| 对象存储语义、缓存模式、CDN 回源 | S3 全部 API、CDN 厂商控制台操作 |
| 分布式锁、租约、fencing token、选主 | 具体产品的锁 API 大全 |
| trace/指标/日志/回放、SLO | 某家 APM 产品的部署手册 |
| 容量、限流、降级、故障演练 | Kubernetes 调度器与容器运行时实现 |
2 不重复清单(硬约束)
以下内容已经在《Linux 系统与内核》中完整讲过。本书只交叉引用,不重写;如果某章需要用到,最多用一两句话提醒,并给出链接。
| 已覆盖内容 | Linux 书位置 | 本书的处理 |
|---|---|---|
| 网络分层、IP、路由、分片 | 4.1–4.3 | 只在解释「请求走哪条路」时引用 |
| UDP/TCP、可靠传输、拥塞控制 | 4.4–4.6 | 超时章节只讲应用层 deadline,不重讲 RTO |
| TCP 建立/关闭、TIME_WAIT | 4.5 | 连接池与重试章引用,不重画状态机 |
| socket、epoll、连接队列 | 4.8–4.11 | 项目章只用 Python 标准库的 HTTP server |
| HTTP、DNS、TLS | 4.7 | 不解释报文;只讲 HTTP 语义对重试的影响 |
| 容器、namespace、cgroups | 5.1–5.5 | 项目不依赖容器,最多用进程隔离 |
| Kubernetes 基础 | 5.6 | 只在「发布与容量」处引用 |
- 把「TCP 超时」当成本书的「请求超时」。TCP 的 RTO 是传输层重传计时器;本书的 deadline 是应用层「我最多等到什么时候」,两者可以差一个数量级。
- 把「HTTP 503」当成一种失败。503 是语义,不是原因;本书要求同时看
Retry-After、连接是否被复用、服务端是否已经执行。 - 把「Kubernetes 重启了 Pod」当成根因。Pod 重启是控制面的动作,根因通常在数据面:探针超时、依赖阻塞、内存泄漏、重试风暴。
3 深度取舍
3.1 协议:讲可判定的部分
Paxos 与 Raft 都讲,但重点不同:
- Paxos 讲安全性从哪来:为什么 prepare 的多数派与 accept 的多数派相交,就能保证只有一个值被选中;为什么活锁不是安全性问题。
- Raft 讲工程实现:term、选举超时、日志匹配、提交规则、ReadIndex、成员变更。因为项目二会实现一个简化版,读者需要能对着代码检查不变量。
不展开:Byzantine 共识、区块链共识、Paxos Made Live 的全部工程细节、Raft 的每一条形式化证明。
3.2 一致性:给判定方法,不给口号
本书用「历史」(history)来定义一致性:一组操作、它们的调用/返回时间、读到的值。线性一致要求存在一个全序,使得每个操作在其调用与返回之间生效,且读到的值符合这个全序。第 4 章会给正例、反例和检查方法(Jepsen 风格的 :ok / :fail 历史)。
不展开:形式化验证工具(TLA+、Coq)的教程;只给一个 TLA+ 风格的伪代码例子,说明「不变量」怎么写。
3.3 事务:单机原理 + 分布式协议
单机部分讲 MVCC 的版本可见性与隔离级别,因为这是理解「快照读」「写偏斜」的基础;分布式部分讲 2PC、TCC、Saga、Outbox,重点是失败路径:协调者挂了怎么办、参与者超时怎么办、重试怎么不重复。
不展开:某个数据库的完整锁系统、buffer pool、B+ 树实现;这些属于存储引擎教材。
3.4 工程:以可观测和可演练为终点
第 9–11 章不是「运维常识合集」,而是把前面所有机制接到三个问题上:
- 锁过期后,怎么保证资源不被两个持有者同时修改?——fencing token。
- 出事时,怎么在 5 分钟内判断是过载、依赖慢、还是重试风暴?——RED/USE + trace + 队列指标。
- 容量怎么估、怎么压、怎么演练?——Little’s law、利用率曲线、故障注入剧本。
4 版本与事实政策
- 协议事实以公开规范/论文为准,例如 Raft 论文、RFC、S3 一致性文档;产品行为标版本。
- 公开事故只写可核对的时间、影响和官方复盘结论;不写「据说」「网传」。
- 代码以 Python 3.11+ 标准库为准;不依赖第三方包,保证
python3 -m unittest在干净环境可跑。 - 图表全部自绘;SVG 的
id全书唯一,状态机与时序图必须能对应到正文的某个不变量。
5 淘汰与迁移
以下内容曾经常见于分布式教材,但本书不展开,原因如下:
| 内容 | 处理 | 原因 |
|---|---|---|
| 3PC | 只在 2PC 对比表出现一行 | 不能解决分区,工程上很少单独使用 |
| 两阶段锁的完整实现 | 用 MVCC 替代讲解 | 现代 OLTP 主流是 MVCC + 短锁 |
| 租约锁的「绝对安全」叙事 | 第 9 章明确反驳 | 租约依赖时钟,必须配 fencing |
| CAP 的「三选二」 | 第 4 章给精确版本 | 口号会掩盖「分区时选什么」 |
| 微服务拆分原则 | 不写 | 属于架构方法论,不是数据面 |
| Service Mesh 数据面实现 | 只在可观测章节提一句 | 属于云原生控制面/代理实现 |
下一站:符号、单位与代码约定——统一记号,避免后面把「延迟」「超时」「deadline」混着用。