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

流处理

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

EN →

这一章讲什么?

你刷信用卡的一瞬间弹出「消费提醒」、打车软件实时挪动的那个小车、直播间蹭蹭涨的在线人数——这些都不能「等到今晚一起算」。上一章的批处理像每天洗一大桶衣服,攒够一批才跑,你看到的永远是「昨天的世界」。这一章讲的是另一种活儿:数据来一条、就处理一条,让结果永远贴着「此刻」——这就是流处理

先打个比方

把每一件发生的事——一次点击、一笔付款、一台传感器的读数——都想成一张写好就不改的小便利贴:「几点几分,谁,干了什么」。流处理就是在便利贴不断飞来的传送带旁边站个人,来一张看一张、随手就把账记上、把该报的警报出了,而不是等一麻袋攒满再拆。

旧世界为什么难

批处理有个改不掉的毛病:它总在等——等数据攒够一批、等整批算完,你拿到的永远是几小时前的旧账。可现实里一大堆事等不起:盗刷要当场拦、大促库存要实时看、故障要立刻报。你总不能为了看一眼此刻,把一整天的数据从头再算一遍。

核心机制直觉

撑起流处理的有两个朴素点子。其一,一条永不删的流水账。别把便利贴看完就扔——把它们一张接一张钉在一条长长的传送带上、永不撕掉;哪个部门要看,就自己带个书签、读到哪记到哪,随时能把书签往回拨、重读一遍(这正是 Kafka 干的事)。其二,账本与余额是一回事。你的银行余额,无非是把所有流水从头加一遍的结果;反过来,只要把每一笔流水都留着,任何时刻的余额都能重新算出来。「存下每一次变化、而不只存最新状态」——这个小小的调头,是整章的魂。

带来了什么 / 该怎么选

有了这条可回放的流水账,一处发生的变化能秒级扇给所有需要它的人:数据库一改,搜索索引、缓存、报表跟着实时更新;风控在你手指离开屏幕前就算完了要不要拦。要「立等可取」的场景就上流,能「今晚跑明早出」的就交给批。一句诚实的代价:一旦追求实时,「时间」本身就变棘手了——地铁里发出的消息可能晚几分钟才到,事件乱序、迟到,让「这一分钟到底发生了什么」永远没有一条铁定的截止线,只能划一道大概的界、承认偶有漏网。

一句话记住

流处理 = 数据来一条算一条,让结果永远贴着此刻,图的是「立等可取」。两根支柱:一条永不删、可回放的流水账(Kafka),和「存每一次变化、而非只存最新状态」——余额不过是流水加总。代价是:实时让「时间」变滑,乱序与迟到的事件没有铁定截止线。

想进到 CDC、流表二象性、窗口与水位、exactly-once 和示意图? → 切到精读版