专业书籍精读 · System Design Interview 卷二 · 第 4 章

设计分布式消息队列

System Design Interview Vol 2 · Ch 4 · Alex Xu & Sahn Lam · 2022

EN →

这一章讲什么?

你在外卖 App 上点了「下单」。那一秒钟里,商家要收到单子、骑手系统要开始派单、库存要扣掉、优惠券要核销、风控要查一遍有没有薅羊毛、数据看板还要加上一笔。这一章讲的就是中间那根传话的管子——而且是教你亲手造一个。

先说个怪事

这个以「快」出名的东西,把每一条消息老老实实写到硬盘上,不是攒在内存里。更怪的是,它比很多只写内存的方案还能扛。

旧世界为什么难

不用这根管子行不行?下单服务挨个去喊:喊商家、喊骑手、喊库存、喊风控。麻烦有三层。

第一,下单服务得认识所有部门,新来一个部门就得改一次下单的代码。第二,风控那边一秒只处理得了五千件事,可大促零点一秒来五万单——喊也是白喊,还会把下单服务一起拖垮。第三,风控那台机器要是重启了,这几分钟的单子就永远没人查了,因为话喊出去就没了。

核心的点子:把「传话」改成「记账」

这根管子真正的样子,不是传声筒,是一本流水账。下单服务不喊任何人,只管往本子的最后一页添一行。谁想知道发生了什么,自己来翻本子,并且自己记住翻到第几行了。

三个麻烦一起解决。下单服务只认识本子,不认识任何部门;风控慢就慢慢翻,本子不会催它;风控重启回来,从自己记的那一行接着翻——账还在,没有谁的消息是「错过了就没了」。新来一个部门更简单,自己从第一行开始翻就是,谁也不惊动。

为什么写硬盘反而快

因为它只往最后一页写。硬盘慢在「翻来翻去找页」,不慢在「一直往后添」。一本只增不改的账本,恰好把硬盘最不擅长的事完全绕开了——这就是它敢用硬盘的全部秘密。

一本不够用,就开好几本

一本账本只有一个人在最后一页写字,再快也有上限。办法是开好几本,按订单号分:尾号 0 到 3 的记第一本、4 到 6 记第二本,几个人同时开工。代价也就在这儿:同一本里的先后顺序绝对可靠,跨本子之间谁先谁后,就说不准了。

一句话记住

消息队列不是传声筒,是一本只能往后添、谁读到哪儿自己记的流水账。它敢把消息写进硬盘,是因为只往末尾写;它能扩展,是因为一本拆成好几本——而拆开的那一刻,你手里就只剩「每本内部有序」这半句承诺了。

想看磁盘布局、副本同步与投递语义的具体机制? → 切到精读版