01 / 导读
导读
引用
Vitillo, R. (2022). Understanding Distributed Systems: What Every Developer Should Know About Large Distributed Applications (2nd ed.). Roberto Vitillo.
章节概要
第二版(2.0.0版,2022年3月)约330页,共34章:一个引言、五个部分(通信、协调、可扩展性、弹性和可维护性)以及一个简短的结语章。前言称第二版是对第一版的全面重写。各章篇幅紧凑,不少只有几页,并在脚注中列出论文、RFC和工程文章,供想深入了解的读者参考;书中没有习题。
第1章:引言
把分布式系统定义为通过交换消息进行协作的一组节点,解释为什么要构建这类系统(应用本身就是分布式的、可用性、单台机器容纳不下的负载、延迟),并预告为五个部分命名的五大挑战。本章用"两将军问题"说明协调为何困难,并介绍吞吐量、响应时间、纵向扩展与横向扩展,以及用"几个9"来衡量的可用性。最后一节从业务逻辑、接口和适配器的角度描述服务的构成(端口与适配器架构)。
第一部分 第2–5章:可靠链路;安全链路;服务发现;API
第一部分逐层搭建分布式应用所依赖的网络协议栈。第2章说明TCP如何在IP之上建立可靠信道:报文段与确认、连接的生命周期与三次握手、流量控制、拥塞控制,以及自定义协议。第3章说明TLS如何在TCP之上加入加密、认证、完整性和握手。第4章把DNS介绍为一个分布式、分层且最终一致的键值存储,这是读者第一次接触最终一致性。第5章讲解RESTful HTTP API:资源、请求方法、状态码、OpenAPI、API演进和幂等性。
第二部分 第6–13章:系统模型;故障检测;时间;领导者选举;复制;避免协调;事务;异步事务
作者称这是全书理论最多、难度最大的部分。本部分先介绍关于进程、链路和时序的系统模型,然后讨论故障检测。第8章讲物理时钟、逻辑时钟和向量时钟;第9章讲Raft领导者选举及实际考量。第10章讨论状态机复制、共识、一致性模型(包括CAP和PACELC所体现的权衡)以及链式复制。第11章转向避免协调的较弱模型:广播协议、无冲突复制数据类型(CRDT)、Dynamo风格的数据存储、CALM定理和因果一致性。第12和13章讨论跨分区或跨服务的事务:ACID、隔离性、原子性、NewSQL系统,以及用于长时间运行的异步事务的发件箱模式和Saga。
第三部分 第14–23章:HTTP缓存;内容分发网络;分区;文件存储;网络负载均衡;数据存储;缓存;微服务;控制平面与数据平面;消息传递
第三部分跟随一个简单的CRUD网络应用逐步扩展的过程,并围绕三种模式组织内容:功能分解、分区和复制。内容从客户端HTTP缓存和反向代理开始,经过CDN、范围分区与哈希分区、Blob存储(以Azure Storage的架构为例),再到基于DNS、传输层和应用层的负载均衡。第19章通过复制和分区来扩展关系型数据库,随后介绍NoSQL存储;第20章讨论缓存策略以及本地缓存与外部缓存。最后三章讨论微服务与API网关、控制平面与数据平面的分离(含一小节控制理论),以及异步消息传递,包括投递保证、恰好一次处理、故障和积压。
第四部分 第24–28章:常见故障原因;冗余;故障隔离;下游弹性;上游弹性
第四部分从常见故障原因的清单开始:硬件故障、错误处理不当、配置变更、单点故障、网络故障、资源泄漏、负载压力和级联故障,并有一节讨论风险管理。随后说明为什么只有在故障互不相关时冗余才有用,如何用洗牌分片和蜂窝架构隔离故障,以及容忍下游依赖故障的模式(超时、重试、断路器)和保护服务免于过载的模式(负载削减、负载平滑、限流、恒定工作量)。
第五部分 第29–33章:测试;持续交付与部署;监控;可观测性;可管理性
最后一部分讨论生产环境中的系统运维。第29章讨论测试的范围和规模,并简要介绍形式化验证。第30章跟随一次变更经过评审、构建、预生产和生产阶段,直到回滚。第31章讨论指标、服务级别指标与目标、告警、仪表盘和值班;第32章通过日志和追踪讲解可观测性;第33章讨论如何通过配置而不是修改代码来改变系统行为。
第34章:结语
一个简短的结束章。
核心概念
第1–5章:引言与通信
- 抽象泄漏:本书讲解TCP、TLS和DNS的原因:网络库会隐藏底层细节,直到出现问题为止。
- 幂等性:设计API操作,使重试请求不会导致操作被执行两次。
- 最终一致性:副本可能暂时不一致,但最终会收敛;读者首先通过DNS接触到它。
第6–13章:协调
- 系统模型:关于进程故障、链路可靠性和时序的一组假设,用于对算法进行推理。
- 逻辑时钟与向量时钟:不依赖同步物理时钟而为事件排序的方法。
- 共识与状态机复制:让各副本对同一操作序列保持一致,书中以Raft为例说明。
- Saga:由带补偿操作的本地步骤组成的长时间事务,用来代替分布式加锁。
第14–23章:可扩展性
- 分区:按键的范围或哈希拆分数据,以便分布到多个节点上。
- 控制平面与数据平面:把配置和元数据的管理与请求的处理分离开来。
- 恰好一次处理:消息系统在消息投递方面能保证什么、不能保证什么。
第24–33章:弹性与可维护性
- 相关故障:具有共同原因的故障,会使简单的冗余失效。
- 断路器:停止调用出故障的依赖,防止故障级联扩散。
- 服务级别目标(SLO):为服务级别指标设定的目标值,用来界定可接受的行为。
评析
优点
- 填补理论与实践之间的空白。 前言指出,这一领域的资料大多集中在学术或实践的两端;本书有意把两者结合起来,因此Raft、CRDT和CALM定理与CDN、负载均衡器和值班实践并列出现。本书网站引用了Gergely Orosz的评价,他认为本书填补了深奥理论书与面试准备类书籍之间的空白。
- 源自生产环境的经验。 作者曾在Mozilla和微软(后来在AWS)从事大规模数据平台工作,这在第三至第五部分体现得很明显,这些部分涵盖了经典教材较少涉及的话题:限流、洗牌分片、蜂窝架构、部署流水线、SLO和可观测性。
- 简短而连贯。 用大约330页覆盖整个领域,每个部分开头都有各章概览,后面的章节也会回扣前文(例如从TCP流量控制联系到服务层面的限流)。作者网站上的免费样章包含前置部分、完整目录和开头几章,读者可以在购买前了解文风。
局限
- 有意重广度而轻深度。 前言明确表示,构建大型系统经验丰富的读者可能会觉得本书不够深入;许多章节只有几页,算法用文字和图示来解释,而不是给出证明。
- 没有习题或项目。 书中没有习题,课程需要自行设计实验。
- 侧重云和后端。 介绍系统构成的一节说明,本书主要关注实现业务服务的后端应用;目录中没有关于并行计算或对等网络系统的章节,若干例子取自特定的云服务。
在课程中的定位
在本课程书单中,Vitillo这本书是最简短、最注重实践的入门读物。van Steen与Tanenbaum的 Distributed Systems 和Coulouris等人的 Distributed Systems: Concepts and Design 是以原理为先的完整教材,对架构、通信、命名、协调、一致性、复制、容错和安全的讨论要深入得多;可以先读Vitillo作为概览,也可以与其中一本并读,看看这些原理在云服务中如何体现。Kleppmann的 Designing Data-Intensive Applications 对数据系统(存储引擎、复制、分区、流处理)的探讨更进一步,是读完第二、三部分后自然的下一步。
Cachin、Guerraoui和Rodrigues的 Introduction to Reliable and Secure Distributed Programming 对Vitillo在第二部分中非形式化讲解的抽象(如系统模型、广播和共识)给出严格的处理。Pacheco和Malensek的 An Introduction to Parallel Programming 涵盖课程的另一面,即为多核处理器、集群和GPU编写并行程序,这是本书没有涉及的内容。
如何使用本书
本书面向从事或准备从事网页和移动应用后端开发的开发者。读者需要有编程经验,并大致了解网络应用的工作方式;不要求理论基础。
- 概览通读: 读第1章和各部分的引言,一个下午就能对这个领域有整体认识。
- 分布式系统课程的核心: 第二部分(第6–13章)需要慢慢读;可以与原理类教材的相应章节配合,并顺着脚注中的论文(例如关于Raft或CRDT的论文)深入。
- 实践者的核心: 第三和第四部分,建议按顺序阅读,因为可扩展性各章是一步步搭建同一个应用的。
- 初读可略: 如果已熟悉TCP、TLS和HTTP,可跳过第一部分;第五部分可以等到参与生产服务时再读。
由于没有习题,动手实现一些小版本会很有帮助:例如向量时钟、带指数退避和抖动的重试策略,或一个简单的基于哈希的分区器。电子版会不定期更新并带有版本号;作者网站提供免费样章。
