专业书籍精读 · DDIA · 第 8 章

分布式系统的麻烦

Designing Data-Intensive Applications · Ch 8 · Martin Kleppmann · 2017

EN →

这一章讲什么?

前面几章都在讲「把数据放到很多台机器上,能得到什么好处」。这一章反过来,专门讲坏消息:一旦你的系统由许多台机器组成、靠网络互相说话,会冒出一大堆单机时代根本不存在的麻烦。DDIA(《数据密集型应用设计》)第 8 章就是把这些坑一个个摊开来吓你——不是让你别做,而是让你别再幻想「一堆机器会像一台大机器那样乖」。

先打个比方

想象你和几个同事分散在不同城市,只能靠寄信联系。你寄出一封信问「这事你办了吗」,然后……杳无音信。问题来了:是信没寄到?是对方病倒了?是他回信了但回信丢了?还是他其实在慢慢办、只是还没回?你根本分不清。一台电脑对着网络另一头的电脑喊话,就是这种感觉——沉默有无数种解释,而你必须在分不清的情况下继续把事情办对。

旧世界为什么反而简单

一台电脑有个好脾气:它要么好好干活,要么彻底崩掉(死机、蓝屏)——崩了你一眼就看见,重启就好。它很少「半死不活」。可一旦是一群电脑,就会出现「部分失效」:有的机器好、有的坏,有的网络通、有的不通,而且你常常没法知道到底哪台出了事。这种「说不清谁坏了」的不确定,才是分布式最折磨人的地方。

三样最不该信的东西

这一章教你对三样东西时刻保持怀疑① 网络——信会丢、会晚到、会乱序,你唯一的工具是「等一会儿还没回就当它没了」,可「等多久」纯靠猜。② 时钟——每台机器的表都走得略有出入,就像一屋子人的手表对不齐,所以你不能靠「谁的表显示得更晚」来判断谁后动手,否则会把数据判错、判丢。③ 突然的停顿——一台机器可能毫无征兆地卡住几秒(就像人说着话突然打了个盹),醒来还以为没事,继续干它早该停手的活。

应对的心法就一句:凡是能出错的都当它会出错,然后设计成「就算出错了,结果照样是对的」。一个经典小招是「编号取号」:给每次操作发一张号码牌,号越来越大;万一你打盹醒来还攥着旧号去办事,柜台一看号过期了,直接拒绝——脏活就干不成了。

该记住什么

分布式系统之所以要用「多数投票」「超时重试」「取号拒旧」这一堆看着啰嗦的机制,正是因为网络、时钟、别的机器,一个都不能全信。诚实的代价是:这套处处设防的机制,让分布式系统比单机慢得多、也复杂得多——这就是「不能信任何东西」要付的学费。

一句话记住

许多机器凑一起,最大的麻烦不是「某台坏了」,而是「某台坏没坏你都说不清」。网络会骗你、时钟会骗你、机器会突然打盹——把它们全当不可信,再设计成出了错也不出乱子,才是分布式的正道。

想进到具体机制、记号和示意图? → 切到精读版