Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

分布式系统与数据面 · 定制教程

分布式系统与数据面

从一次工具调用出发,沿请求、复制、事务、消息、缓存与观测一路走到可验证的一致性。
5 篇 · 13 章 2 个可运行项目 只用 Python 标准库 章末陷阱清单与出口检查
查看范围、前置与边界
前置:TCP 三次握手、socket、epoll、HTTP、DNS、TLS 读《Linux 系统与内核》第 4 篇;容器与 Kubernetes 基础读第 5 篇。本书只写数据面,不重写 TCP/HTTP/K8s 基础。
两个项目都只用 Python 标准库,不依赖 Docker 或云账号;协议事实以 2026 年仍有效的规范与实现为准,依赖版本的结论都标了版本。
CONTENTS / 目录5 篇 · 13 章 · 2 个项目

左侧目录是完整导航;页首搜索支持全文检索。第一次来,先读 三条阅读路线,再从 第 1 章 开始。

ROUTE 01 · 后端工程师 把一次调用写对

第 1、2 章精读远程调用的状态与重试预算;第 6 章精读 MVCC,第 7、8 章选读;第 12 章做项目一,注入丢响应故障,证明副作用只发生一次。约 12–16 小时。

展开路线 →
ROUTE 02 · SRE / 平台 把故障看清楚

先快读第 1 章的失败分类,再精读第 3、9、10 章的分区、租约与观测;第 11 章写一份爆炸半径受控的演练剧本。约 10–14 小时。

展开路线 →
ROUTE 03 · 存储 / 基础设施 把一致性讲清楚

精读第 3、4、5 章的复制拓扑、线性一致判定与 Raft,用第 6 章的 MVCC 解释可见性;第 13 章做项目二。约 16–20 小时。

展开路线 →
这本书回答

一次工具调用离开本机之后,为什么会出现「超时了但已经成功」「重试一次扣了两次钱」「主库切换后刚写的记录不见了」「扩容之后 p99 反而更高」?这些问题不是名词不够多,而是失败模型、一致性契约和容量边界没有写清楚。

读完之后

你能为一个远程调用写出超时、重试、幂等与背压的完整契约;能判断该选主从、多主还是无主;能读懂 Raft 的选举与提交;能用 MVCC 解释隔离级别;能把队列、缓存、CDN、锁、观测和容量串成一条可验证的数据面。

分布式系统最容易写成两本错的书。

第一本错在只讲名词:CAP、BASE、最终一致、服务网格、云原生、可观测性,每一页都有新词,合上书却画不出一条请求的路径,也解释不了一次重复扣款。第二本错在只讲协议:Paxos 的两个阶段、Raft 的五个状态、2PC 的投票与提交都写对了,但读者不知道这些协议在业务代码里对应哪一行,也不知道超时该设 200 ms 还是 2 s。

这本书想写第三本:从一次具体的工具调用出发,沿着请求、复制、事务、消息、缓存和观测一路走,每到一个概念都问三件事——它解决什么失败、代价是什么、怎么观测。 协议是骨架,失败是血肉,观测是证据。

这本书的位置

它不是《Linux 系统与内核》的续集,也不是微服务名词表。它假设你已经知道 TCP 三次握手、socket、epoll、HTTP、DNS、TLS 的基本工作方式;这些内容在 Linux 书第 4 篇 已经讲过,本书只引用、不重写。容器与 Kubernetes 的基础同理,见 Linux 书第 5 篇。

本书只写数据面:请求怎么发、失败怎么判、状态怎么复制、事务怎么提交、消息怎么投递、缓存怎么失效、锁怎么过期、指标怎么解释、容量怎么估。控制面(调度、编排、服务发现、配置下发)只在必要时出现,而且从不展开成产品手册。

                  ┌──────────────────────────────────────────────┐
                  │  一次工具调用的数据面(本书主线)              │
                  └──────────────────────────────────────────────┘
   客户端            接入层              服务层                 状态层
  ┌────────┐      ┌────────┐        ┌────────────┐        ┌──────────────┐
  │ 重试   │─────▶│ 限流   │───────▶│ RPC/事务   │───────▶│ 复制日志     │
  │ 超时   │      │ 鉴权   │        │ 幂等键     │        │ 共识/选主    │
  │ 幂等键 │      │ 路由   │        │ 背压       │        │ MVCC/队列    │
  └────────┘      └────────┘        └────────────┘        └──────────────┘
       │                │                  │                     │
       └────────────────┴──────────────────┴─────────────────────┘
                    观测:trace / metrics / logs / replay

读这张图要抓住一个事实:同一份「一次调用」会在六个地方留下状态——客户端的内存、接入层的连接、服务端的请求上下文、数据库的事务、复制日志的位置、观测系统的 span。一次重复副作用,往往是其中两个状态对不上:客户端认为失败了,服务端已经提交了;服务端认为只执行了一次,复制日志里却有两条。

全书地图

篇章回答的问题关键产物
第 1 篇 请求与失败1–2一次远程调用为什么会「未知」;超时、重试、幂等、背压怎么组合远程调用契约、重试预算、幂等状态机
第 2 篇 复制与一致3–5数据放在几台机器上;读到旧值算不算错;共识到底保证什么复制拓扑、一致性契约、Raft 检查表
第 3 篇 数据与消息6–8事务边界在哪;消息为什么重复;缓存为什么越缓存越旧MVCC 读法、投递语义、缓存失效策略
第 4 篇 运行与治理9–11锁过期了怎么办;出事时看什么;容量和演练怎么做fencing token、观测面板、故障演练剧本
第 5 篇 项目12–13把前四篇压成两个能跑的服务幂等工具调用后端、三节点复制 KV

每一章都按同一个骨架写:先给一条真实请求或一次真实故障,再拆机制,再给边界与观测命令,最后落到「如果你来实现,必须回答哪些问题」。章末有 8–15 条陷阱清单和出口检查;陷阱不是「注意安全」这种空话,而是「把 Retry-After 当建议、把超时当失败、把 RPO=0 当默认」这类会直接导致事故的判断。

两个项目

纸上的协议必须落到进程上。第 12、13 章是两个可运行的项目,代码在 projects/:

  • 项目一 · 幂等工具调用后端:HTTP + SQLite,带幂等键、请求指纹、租约、崩溃恢复、丢响应故障注入。你会亲手制造「服务端成功了,客户端超时了」,再用同一个键重试,证明副作用只发生一次。
  • 项目二 · 小型复制 KV:三个 Python 进程,简化 Raft 选举与日志复制,支持线性一致读、租约读和陈旧读;用分区脚本把主节点隔离,观察旧主如何被 fencing 挡住。

两个项目都只用 Python 标准库,python3 -m unittest 可跑,故障注入脚本 bash -n 通过,且不依赖 Docker 或云账号。它们不是玩具:每个不变量都有对应的测试,每个测试都对应正文的一节。

不做什么

  • 不重写 TCP/IP、socket、epoll、HTTP/DNS/TLS;这些在 Linux 书第 4 篇。
  • 不重写容器、Kubernetes 基础与云原生编排;这些在 Linux 书第 5 篇。
  • 不把 CAP 当口号。第 4 章会给出可判定的定义、反例和检查方法;只喊「三者选二」的段落不会出现。
  • 不把分布式写成微服务名词表。每个名词必须能落到一条请求路径、一个状态字段或一条观测命令。
  • 不复制母本原文、代码或图。所有图由本书自绘,所有代码为本书编写,公开案例只引用事实与链接。
版本与时间

本书的协议事实以 2026 年仍有效的规范与实现为准:Raft 以 Ongaro & Ousterhout 的论文与 etcd 3.5 的行为为参照;MVCC 以 PostgreSQL 16 与 InnoDB 8.0 为参照;对象存储以 S3 的强一致模型为参照。产品行为会变,书中凡是依赖版本的结论都标了版本;没有标版本的,按「截至 2026 年公开文档」理解。

下一站:如果你想知道这本书为什么值得单独写,读 为什么写这本书;如果你要先确认自己是否准备好了,做 入学诊断。

COLOPHON / 题记 分布式系统与数据面 · 定制教程;协议与产品行为以公开规范和实现为准,依赖版本的结论都标了版本。 MDBOOK · 2026-10