Skip to content
知识

/knowledge/streaming-analytics

流式与实时分析

大多数分析都等着夜间的批处理。有些问题等不了——正在发生的欺诈、阈值一被触发那一刻的警报。把数据当作一条连续、永不停止的流来处理,是一门不同的学问,有它自己关于时间的巧妙想法。

学于
流式与实时分析实务 · 运动中的数据
时间
数据工程 · 进行中
应用于
实时监控与警报
阅读 / 复习
约 14 分钟阅读2026-06-26

这一节里几乎所有东西都假设批处理:你有一个数据集,你分析它,你得到一个答案。但有一整类 问题等不了数据集变完整——你需要在数据到达时就得到答案。在欺诈发生那一刻抓住它、在一个传感器 越过阈值时发警报、更新一个实时仪表盘——这些需要流处理:连续地、作为一股无尽的事件流来 分析数据,而非分周期地成批分析。

它是一门真正不同的学问,而不只是「批处理但更快」,因为数据是无限的——而那一个事实 逼出一些巧妙的重新思考,尤其是关于时间。这一页讲实用的地形:流式与批处理有何不同、让无限数据可处理的 开窗想法、「一个事件何时发生」这个微妙的问题,以及运行它的技术栈。它建立在分布式计算页之上。

01

批处理对流处理:根本的分野

这两种范式回答不同的问题。批处理在一个有界的数据集上运行——昨天所有的 交易——并产出一个完整、正确的答案,但只在数据被收集、作业运行之后(数分钟到数小时的延迟)。流处理在一股无界的流上运行——每笔交易在它发生的那一瞬间——以亚秒级的延迟 产出连续更新的答案。

取舍是延迟对完整性。批处理更简单、给你完整的图景,但来得晚;流式是即时的,但必须对仍在到达的 数据进行推理。当答案的及时性值那份额外的复杂度时——当一个小时后的答案毫无价值时——你才 动用流式。

02

永不结束的数据

那个决定性的挑战是,一股流是无限的。你没法「加载数据集」——没有尽头。你没法计算 一个简单的平均值,因为这个平均值所覆盖的数据永不停止增长。每一个熟悉的聚合,都得为一股不会结束的 流重新思考。

一股流是一串事件,每一个都是一条盖了时间戳的、小而不可变的记录——一次点击、一笔交易、 一个传感器读数。处理必须是连续有状态的(它在事件流经时记住一个运行中的 概括),因为它永远没法回头去重读整段历史。让无限数据变得可处理的关键一步,是把它切成有限的小块。

03

开窗:把无限变成有限

你没法对一股无限流的「全部」求平均,但你可以对「最近五分钟」求平均。一个窗口是 流的一个有限切片,你在它上面做计算——而开窗是流处理的核心想法。主要的种类:

滚动滑动
在一股事件流上的两种开窗风格。滚动窗口是固定的、首尾相接、不重叠的切片(每个事件恰好在一个里)。滑动窗口相互重叠,以一小步推进——给出一个平滑的滚动聚合,其中每个事件落在好几个窗口里。
  • 滚动——固定大小、不重叠(「每 5 分钟」)。每个事件恰好属于一个窗口。适合规则的、 离散的聚合。
  • 滑动——固定大小但相互重叠,以一小步推进(「最近 5 分钟,每 30 秒更新」)。每个事件 落在好几个窗口里——是平滑滚动平均的理想之选。
  • 会话——由活动间隙定义的动态窗口(一个用户的一阵点击,在他们安静下来后关闭)。窗口 大小随数据自适应。

04

事件时间、处理时间与水位线

这里有一个流式独有的微妙问题:每个事件都有两个不同的时间,而把它们搞混会污染你的 结果。

  • 事件时间——事件实际发生的时刻(在源头盖的戳)。
  • 处理时间——你的系统接收并处理它的时刻。

在一个完美的世界里它们会一致。现实中,事件迟到且乱序地到达——一部手机失去信号, 二十分钟后才上传它的读数,于是一个在 3:00 发生的事件直到 3:20 才到达。如果你按 处理时间分桶,那个读数会落进错误的窗口,你的「3:00–3:05」总数就错了。你几乎总是想按事件 时间聚合,才能得到正确的答案。

05

投递保证

当事件流经一个可能在中途失败的分布式系统时,一个难题就出现了:如果一台机器崩溃并重启,每个事件是 被处理了一次、一次都没有,还是两次?这些保证:

  • 至多一次——事件可能在失败时被丢弃。快、有损;很少可接受。
  • 至少一次——没有事件丢失,但有些可能在重试时被处理两次(所以一个计数可能多报)。 常见的默认。
  • 恰好一次——黄金标准:每个事件恰好影响结果一次,即便经历失败也是如此。靠检查点和 细致的协调来实现——更昂贵,但在重复计数会成为真正的问题时(钱、合规)是必不可少的。

你需要哪一种,是一个与一次错误的成本绑定的真正工程决定——是可信流水线那个关切在流式里的回响。

06

技术栈

一个流式系统通常分成两个角色。一个消息代理——Kafka 是标准——是那条 持久的管道:它摄入事件,把它们存放在有序的日志里,好让生产者和消费者解耦、且什么都不丢失。一个流处理器——Flink,或 Spark Structured Streaming(绑定到Spark 引擎)——做实际的计算:上面讲的开窗、 有状态的聚合、事件时间逻辑。

你还会听到 LambdaKappa 架构——大体上,是你运行分开的批处理层和流式层 (Lambda),还是把一切都当作流来处理(Kappa)。还有与机器学习的联系:流式是在线学习MLOps 页里那种实时漂移检测的天然归宿——一个随数据 流动而被更新或监控、而非每夜重训的模型。

07

它在我工作中的体现

08

60 秒回顾

批处理对流处理的分野、窗口类型、事件时间/水位线处理,以及投递保证,反映了当前的流处理参考文献 (Kafka/Flink 实践)以及动手工作。