一、流批一体概述:从两条河到一条江
大家好,我是这次课程的主讲。在数据架构这个领域摸爬滚打了十几年,我见过太多团队在实时和离线之间反复横跳。今天咱们先聊聊流批一体的来龙去脉,把地基打牢。
1.1 流计算与批处理的发展历程
批处理的历史其实比流计算长得多。早年间,数据都是 T+1 算的——今天的数据,明天出报表。MapReduce 是那个时代的代表,虽然慢,但胜在稳定。
后来业务方不满足了。他们问:「能不能看到实时的用户行为?」于是流计算开始冒头。Storm 是第一波,接着 Spark Streaming 用微批的思路打了个擦边球,再后来 Flink 真正做到了「来一条处理一条」。
我个人习惯把这段历史分成三个阶段:
- 批处理时代(2000s-2010s):Hadoop、Hive、Spark SQL。数据量大,延迟高,适合报表和离线分析。
- 流计算兴起(2010s-2015):Storm、Spark Streaming、Flink 早期。低延迟,但和批处理是两套代码、两套集群。
- 融合探索期(2015-至今):Kafka Streams、Beam、Flink SQL。大家开始意识到,为什么不能写一套代码跑两种场景?
核心认知:流和批本质上是同一枚硬币的两面。流是无限的批,批是有限的流。这个观点我最早在 Flink 社区听到,后来在项目中反复验证,确实如此。
1.2 Lambda 架构与 Kappa 架构的对比
说到流批一体,绕不开两个经典架构:Lambda 和 Kappa。我在 2016 年参与过一个电商大促项目,当时用的就是 Lambda 架构,那叫一个痛苦。
Lambda 架构:两条腿走路
Lambda 架构把数据处理拆成两条链路:
- 批处理层:处理全量历史数据,保证准确性。
- 流处理层:处理实时增量数据,保证低延迟。
- 服务层:合并两边的结果,对外提供服务。
听起来很完美对吧?但实际用起来,问题不少。
我曾经踩过的坑:同一个业务逻辑,要在批处理和流处理里各写一遍。两套代码,两套部署,两套监控。一旦逻辑对不上,数据就对不齐。有一次凌晨三点被叫起来,就是因为批处理和流处理算出的 GMV 差了 0.5%,排查了整整四个小时才发现是窗口函数实现不一致。
Lambda 架构的优缺点很明显:
| 维度 | Lambda 架构 |
|---|---|
| 准确性 | 高(批处理保证全量重算) |
| 延迟 | 低(流处理保证实时) |
| 开发成本 | 高(两套代码) |
| 运维成本 | 高(两套集群) |
| 数据一致性 | 难保证(两套逻辑可能不一致) |
Kappa 架构:一条路走到黑
Kappa 架构的思路很简单:既然流处理能处理无限数据,那为什么不能把历史数据也当成流来重放?
说白了,Kappa 只有一条链路——流处理。历史数据通过 Kafka 等消息队列重放,流处理引擎从头消费一遍,就相当于做了批处理。
这个想法很优雅,但有个前提:你的消息队列必须能保存全量历史数据,并且流处理引擎要支持 exactly-once 语义和状态回溯。
我的建议:如果你的数据量在 TB 级别以内,且业务对实时性要求高,Kappa 架构是更好的选择。但如果数据量到了 PB 级,或者需要频繁回溯几个月的数据,Lambda 架构可能更现实。说白了,没有银弹。
1.3 流批一体的核心价值
流批一体要解决的根本问题是什么?我总结了三句话:
- 一套代码:同一个逻辑,不需要在批和流里各写一遍。
- 一套引擎:Flink、Spark 等引擎同时支持批和流模式。
- 一套数据:实时和离线数据共用同一份存储,不需要来回搬运。
你想想看,如果这三件事都做到了,开发效率能提升多少?运维成本能降低多少?
下面这张图展示了流批一体的核心逻辑:
从这张图你能看到,流批一体的核心在于「统一」二字。数据源进来后,先落到统一存储层,然后流处理和批处理共用同一套计算引擎,最终输出统一的结果。
这样做的好处是什么?
- 开发效率翻倍:写一次逻辑,跑两种模式。我在项目中实测过,开发周期缩短了 40% 以上。
- 运维成本减半:一套集群,一套监控,一套告警。不用再维护两套环境。
- 数据一致性有保障:同一份代码,同一个引擎,算出来的结果天然一致。
一句话总结:流批一体的本质,是用一套技术栈同时覆盖实时和离线场景,让数据工程师从「两套代码、两套集群」的泥潭里解放出来。
嗯,这一章的内容就到这里。流批一体的概念和架构我们已经理清了,后面我们会深入每个技术细节,从 Flink 的批流一体实现,到实际项目中的落地案例,一步步带你掌握这套体系。