序言
十几年前我就想写这本书,因为各种原因一直拖到现在。这本书能写成,多亏有了 AI 的辅助。但我一直不满意 AI 写出的内容,又花了大量时间手工修改,前后仍用了近一年。
很多年前我就发现,日常开发中遇到的一些设计难题,与计算机底层设计面对的问题有相通之处。比如,硬盘、内存和 CPU 缓存怎样协同,多核 CPU 怎样处理并发任务,前人都已给出了各自的解决办法。这些办法值得借鉴,而我更想弄明白的是:面对有限的资源和不同的要求,他们为什么这样设计,又作出了哪些取舍?
不过,我和同事交流时,常常遇到一个困难:从计算机底层原理讲起,不容易把这份感受说清楚。后来我发现,大家熟悉的 Redis、MySQL、Kafka 也是很好的观察样本。围绕它们讨论设计选择,更容易把这些思路与日常开发联系起来。
学习软件时,我们常常沿着它自己的资料往下钻,比如想学 Redis,就找 Redis 的书或课程。再后来,我换了一个角度,围绕“系统如何优雅关闭”这个问题,把不同软件的做法放在一起比较,就有了完全不同的启发。
从这种“横切”角度重新学习和对比这三个软件时,我有了一种和原作者对话的感觉:没有完美的设计,每个软件都在优先满足某些需求,同时接受其他方面的代价。支撑核心目标的设计,也会带来恢复、资源管理和协作问题。解决这些问题的工作看起来不如核心功能显眼,却决定系统能不能稳定运行。比如,Redis 把数据放在内存里,降低了访问延迟,也需要考虑重启后如何恢复;有了多个副本,还要处理数据同步与故障切换。这些问题贯穿它的启动、关闭和集群设计。在这样的横向比较中,“取舍”“务实”“巧思”是我最常想到的几个词。
这本书更想讨论用法和原理背后的设计选择:为什么这样设计,选了之后需要承担什么代价。
AI 让写代码越来越快,也可以快速输出很多版本的技术方案。方案是否合适很难有标准答案,因为周期、成本、团队和遗留系统等现实条件各不相同。我更关心的是,使用这些工具的人能否结合具体条件作出判断,并清楚自己需要为这些抉择承担什么后果。无论 AI 辅助编程多么强大,高级开发者和架构师都需要这份能力。它影响着系统的复杂度、上线进度、扩展能力和运维成本。
我在本书里分享三个层面的内容。
第一层:读懂这三个软件怎样解决具体问题。这些问题在我们日常开发的系统里也经常出现。比如,数据结构怎样设计,启动时怎样恢复状态,关闭时怎样处理尚未完成的请求,内存和磁盘怎样协同,系统怎样分层,权限、分片、容错、存储格式和副本同步又该怎样设计。把这些解法融会贯通,下次遇到类似的设计问题,就更有把握作出合适的选择。
第二层:这三个软件各自放弃了什么、又换回了什么。取舍,是架构设计里最难也最有价值的部分。只知道有哪些可选方案不够,还要理解这些软件为什么这样取舍。我希望你每读完一章,都能合上书想一想:换成自己的系统,会如何取舍?
第三层:怎么把各个环节的方案组合成一个能落地的整体。一个系统牵涉很多技术问题,每个都有多种解法,排列组合下来就是几乎无限的可能性。难点在于根据具体约束去判断和选择:什么时候上线、跑在什么机器上、团队什么情况、遗留系统怎么处理、公司有什么硬性约束。在这些条件下如何作出架构决策,没有万能公式。取舍时,要分清哪些要求可以放宽,哪些底线必须守住。
各个环节不必单独做到最优,但组合起来必须满足系统的整体目标。Redis 围绕低延迟组织内存访问,Kafka 围绕吞吐组织顺序追加和批量消费。掌握具体方案是基础,更难的是在复杂约束下把它们组合成合适的系统。
这本书适合有两年以上开发经验的后端工程师、软件架构师以及技术负责人。如果你对某些知识点不熟悉,可以多用 AI 帮助自己快速了解。
希望你读完之后,面对一个新系统时,会多问一句“为什么这样设计”;设计自己的系统时,能说清为什么这样选,也知道需要为此付出什么代价。