1. 流批一体概述:为什么需要流批一体?
做大数据架构这些年,我见过太多团队在实时和离线两条线上来回折腾。说白了,流批一体不是技术噱头,是被业务逼出来的。今天咱们就从最根本的问题聊起——为什么我们需要流批一体?
1.1 传统架构的痛点:两条腿走路
先回忆一下传统做法。大多数公司早期都是这样:
- 离线批处理:用 Hive/Spark 跑 T+1 报表,数据准,但慢。
- 实时流处理:用 Storm/Flink 做秒级监控,数据快,但可能丢或重复。
两套系统,两套代码,两套运维。你想想看,同样的业务逻辑要在批和流里各写一遍,维护成本直接翻倍。我在一家电商公司就遇到过这种事——离线算的 GMV 和实时算的 GMV 差了 3 个点,两边开发互相甩锅,最后发现是窗口聚合逻辑没对齐。
核心矛盾:业务既想要实时的时效性,又想要离线的准确性。传统架构无法同时满足。
1.2 Lambda 架构:一个妥协的方案
为了解决这个问题,Nathan Marz 提出了 Lambda 架构。它的思路很简单——两条路都保留,最后合并结果。
Lambda 架构分三层:
- 批处理层:全量数据,保证准确性
- 流处理层:增量数据,保证低延迟
- 服务层:合并批和流的结果,对外提供服务
听起来挺合理对吧?但实际用起来问题不少。我曾经维护过一个 Lambda 架构的推荐系统,批处理用 Spark,流处理用 Flink。每次改特征逻辑,两边都得改,而且合并层经常出现时间窗口对不齐的情况。说白了,Lambda 架构只是把问题从「选批还是选流」变成了「怎么让批和流结果一致」。
避坑指南:我曾经见过一个团队在 Lambda 架构上跑了两年,最后发现服务层的合并逻辑比批和流加起来还复杂。如果你团队规模不大,Lambda 架构的维护成本可能会吃掉所有实时收益。
1.3 Kappa 架构:简化但不够完美
后来 Jay Kreps 提出了 Kappa 架构。它的核心思想是——只用一套流处理引擎,通过重放历史数据来达到批处理的效果。
Kappa 架构的好处很明显:
- 一套代码搞定批和流
- 没有合并层的复杂度
- 数据一致性更容易保证
但问题也来了——历史数据重放很慢。我做过一个测试,用 Flink 重放 30 天的 Kafka 数据,跑了将近 4 个小时。如果业务需要频繁回溯修正,Kappa 架构的时效性就扛不住了。
| 对比维度 | Lambda 架构 | Kappa 架构 |
|---|---|---|
| 代码维护 | 两套代码,维护成本高 | 一套代码,维护简单 |
| 数据准确性 | 批处理保证最终准确 | 依赖流处理语义保证 |
| 历史回溯 | 批处理天然支持 | 需要重放,性能瓶颈 |
| 资源消耗 | 两套集群,资源浪费 | 一套集群,资源节省 |
| 运维复杂度 | 高,需要协调批流结果 | 低,单一引擎运维 |
1.4 流批一体:取长补短
所以你看,Lambda 和 Kappa 各有各的短板。流批一体的思路就是——用一套引擎、一套代码、一套存储,同时支持实时和离线场景。
具体来说,流批一体要解决三个核心问题:
- 统一编程模型:批和流用同一套 API,同一个逻辑
- 统一存储:实时数据和离线数据共享同一份存储
- 统一调度:批任务和流任务在同一个调度体系下管理
我个人习惯把流批一体理解为「用流的方式处理实时数据,用批的方式保证数据质量」。说白了,实时数据先出,保证时效性;离线数据后补,保证准确性。两者最终要能对得上。
我的经验:流批一体不是要消灭批处理,而是让批处理成为流处理的「兜底机制」。实时数据出错了?没关系,离线回填会帮你修正。这才是流批一体的核心价值。
1.5 离线回填:流批一体的关键场景
离线回填,说白了就是用离线批处理来修正或补充实时流处理的结果。这是流批一体架构中最常见、也最实用的场景。
我举几个实际例子:
- 电商大促:实时大屏展示 GMV,但数据可能因为网络延迟或系统抖动有偏差。第二天用离线任务回填修正,保证财报数据准确。
- 广告计费:实时扣费要快,但可能因为点击去重不及时多扣了。离线回填做最终结算,多退少补。
- 用户画像:实时标签更新快,但可能因为特征缺失不准确。离线回填用全量数据重新计算,覆盖实时结果。
离线回填的核心流程是这样的:
这个流程里有个关键点——回填不能覆盖实时数据,而是要合并。我见过有人直接用离线结果覆盖实时表,结果实时查询的延迟从秒级变成了小时级。正确的做法是分层存储:实时层用高性能存储,离线层用低成本存储,回填时只修正有问题的部分。
避坑指南:我曾经在一个项目中,离线回填任务跑得太慢,导致实时数据被覆盖前已经被下游消费了。结果就是——实时数据不准,离线数据也没赶上。后来我们加了版本号和时间戳,才解决了这个问题。记住:回填要有版本控制,不能无脑覆盖。
1.6 本章小结
聊了这么多,其实核心就一句话:流批一体的本质,是用一套架构同时满足实时和离线的需求,而离线回填是落地这个架构最关键的场景。
后面的章节,我会带你一步步实现一个完整的离线回填系统。从技术选型到代码实现,从性能优化到线上运维,咱们一个一个来啃。