专业书籍精读 · Database Internals · 第 8 章

分布式系统引论

Database Internals · Ch 8 · Alex Petrov · 2019

EN →

这一章讲什么?

你在手机上点一下「确认支付」,这条消息要跨过基站、光纤、好几台机房里的机器,最后落到某个数据库上。前七章讲的都是一台机器内部怎么存怎么找。从这一章起,故事换了一个场地:多台机器之间,只能靠互相喊话来合作。这一章不教任何具体做法,它先告诉你:在这种场地上,有哪些事从原理上就办不到。

先说个怪事

你给朋友发消息问「今晚八点行吗」,等了十分钟没回。可能是消息没送到;可能是他回了、但回复丢在路上;也可能他正低头打字。这三种情况,你从外面看完全一样。分布式系统里最硌人的就是这个「看起来一样」——超时了,你并不知道对方是死了、是慢了,还是回话丢了。

旧世界为什么难

在一台机器上写程序,有三件事是白送的:调用一个函数,它一定会返回;读一个变量,读到的就是最新值;看一眼表,时间总是往前走。跨到两台机器,这三条一条不剩:函数调用变成了「寄一封信出去,可能永远没有回音」,「最新值」变成了「我上次听说的值」,两块表还可能一快一慢差出好几秒。

它怎么做到的

这一章的做法不是给解药,而是先把话说死——把含糊的「网络不太靠谱」变成三张写明白的假设表,后面所有算法都照着这三张表设计:

所以该怎么选

承诺越强,代价越大。最典型的是「不多不少、正好送到一次」——这件事在线路层面做不到:发信人收到失败时,永远分不清是「没送到」还是「送到了但回执丢了」。真正能做的,是多寄几次,让收件人按单号去重。支付的幂等键、消息队列的去重表,都是这一条的实例。

诚实的代价:这三张假设表买来的是「能讲清楚为什么对」,而不是可靠本身——假设定得太宽松,算法根本跑不动;定得太乐观,真实世界抽一次风就全盘崩。

一句话记住

分布式难的不是机器多,而是没有任何人能看见「现在」。每台机器手里只有一份过期的传闻。工程上唯一能做的,是先把「线路多可靠、时钟多可信、节点会怎么坏」写死成假设,再在上面盖楼。

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