1. 流批一体概述:流批一体的概念、为什么需要流批一体、Lambda架构与Kappa架构对比

1.1 流批一体到底是什么?

先说说我对流批一体的理解。说白了,就是一套代码、一套引擎,同时搞定实时流处理和离线批处理。你想想看,以前我们做数据开发,实时用 Flink,离线用 Spark,两套代码两套运维,光维护就够头疼的。

流批一体的核心思想,是把「流」和「批」看作同一枚硬币的两面。流是无限的批,批是有限的流。嗯,这句话我经常在团队里念叨。从计算引擎的角度看,批处理其实就是流处理的一个特例——数据源有界而已。

流批一体的本质:同一份数据,同一套逻辑,同一套运维。不管数据是实时到达还是批量落地,计算引擎都能用统一的方式处理。

我在项目中遇到过不少团队,号称做了流批一体,结果呢?实时用 Flink SQL,离线用 Hive SQL,中间靠一个「数据同步任务」把实时表导成离线分区表。这哪是流批一体?这叫「流批两套,中间加个胶水层」。真正的流批一体,应该是逻辑层统一、执行层自适应。

1.2 为什么我们需要流批一体?

这个问题,我估计每个大数据从业者都想过。我个人的体会,核心原因就三个:

  • 开发效率太低——两套代码,两套部署,两套监控。改一个业务逻辑,实时和离线各改一遍,还经常改出差异来。
  • 数据一致性难保证——实时算出来的结果和离线算出来的对不上,业务方天天来问「到底信哪个?」。我曾经被这个问题折磨了整整一个季度。
  • 运维成本高——两套集群、两套调度、两套资源管理。你想想看,光是大促期间同时保障两套系统的稳定性,就够运维团队喝一壶的。

还有一个容易被忽略的点:数据新鲜度与计算成本的平衡。有些场景需要秒级延迟,有些场景小时级就够了。如果只有一套实时架构,所有任务都跑在流引擎上,资源浪费惊人。如果只有批架构,实时需求又满足不了。流批一体给了我们「按需选择」的能力。

我的建议:不要为了流批一体而流批一体。如果你的业务场景要么纯实时、要么纯离线,两套系统各司其职也挺好。流批一体最适合的是「同一份数据既有实时需求又有离线需求」的场景。

1.3 Lambda 架构:曾经的王者

说到流批一体,绕不开 Lambda 架构。我记得 2015 年左右,Lambda 架构几乎是大数据领域的标配。它的思路很直白:

  • 批处理层:处理全量历史数据,保证准确性
  • 流处理层:处理实时增量数据,保证低延迟
  • 服务层:合并批结果和流结果,对外提供服务

听起来很完美对吧?但我在实际项目中踩过不少坑。最大的问题是:批结果和流结果怎么合并? 你算一个 UV,批层算出来是 100 万,流层算出来是 102 万,差了 2 万。这 2 万是重复了还是漏了?没人说得清。

我曾经踩过的坑:有一次做实时大屏,Lambda 架构下批结果和流结果差了 5%。业务方指着大屏问「这个数到底对不对?」我查了三天,最后发现是流处理层的去重逻辑和批处理层不一致。从那以后,我对 Lambda 架构的「合并层」格外警惕。

Lambda 架构的另一个痛点:代码维护两套。批处理用 Spark,流处理用 Flink,同样的业务逻辑写两遍。改一个指标口径,两边都得改,还容易改漏。

3.4 Kappa 架构:流式原教旨主义

Kappa 架构的出现,某种程度上是对 Lambda 架构的「反叛」。它的核心理念就一句话:一切皆流。所有数据都走流处理通道,批处理只是流处理的一个特例——把历史数据重新「回放」一遍而已。

我刚开始接触 Kappa 架构时,觉得这想法太激进了。但后来在一个日志分析项目中试了一把,发现确实有它的道理:

  • 一套代码,一套引擎,运维简单
  • 没有「合并层」,也就不存在数据不一致的问题
  • 历史数据重算方便,改完逻辑直接回放就行

但 Kappa 架构也不是银弹。我在实践中发现几个硬伤:

  • 消息队列的存储成本——Kafka 虽然能存数据,但存个几百 TB 试试?成本比 HDFS 高太多了。
  • 历史数据回溯的性能——全量重算时,流引擎处理历史数据的吞吐往往不如专门的批引擎。
  • Exactly-Once 的代价——流处理要做到端到端的 Exactly-Once,复杂度比批处理高一个量级。

3.5 Lambda vs Kappa:一张表说清楚

对比维度 Lambda 架构 Kappa 架构
代码维护 两套代码(批+流) 一套代码(纯流)
数据一致性 合并层容易出偏差 天然一致(无合并)
历史重算 批层直接重算,效率高 流回放,速度受限于引擎
存储成本 HDFS 成本低 消息队列存储成本高
运维复杂度 高(两套集群) 低(一套集群)
适用场景 对准确性要求极高,且批流差异大 实时为主,历史重算需求少

你可能会问:那到底选哪个?我个人的经验是:别二选一,看场景。如果你的业务以实时为主,偶尔需要重算历史,Kappa 更合适。如果你的业务既有大规模离线报表,又有实时大屏,Lambda 可能更稳妥。当然,现在很多新引擎(比如 Flink 的批流一体模式)已经在模糊这个界限了。

3.6 流批一体的核心挑战

不管是 Lambda 还是 Kappa,流批一体要落地,有几个绕不开的坎:

  • 语义统一——同一套 SQL,在流模式和批模式下要算出一致的结果。这涉及到窗口语义、状态管理、迟到数据处理等一系列问题。
  • 存储统一——实时数据存消息队列,离线数据存 HDFS,中间怎么无缝衔接?现在很多方案用「分层存储」来解决。
  • 调度统一——流任务常驻,批任务周期性触发,怎么在一个调度系统里统一管理?嗯,这就是咱们这门课要重点讲的内容。
  • 容错统一——流任务的 Checkpoint 和批任务的 Task 重试,本质上都是「失败后从某个一致点恢复」,但实现机制完全不同。

一个小建议:刚开始做流批一体时,别追求一步到位。先从「统一 SQL 层」入手,让实时和离线用同一套逻辑写代码。存储和调度可以慢慢统一。我在团队里就是这么推的,效果还不错。

3.7 流批一体的知识体系

下面这张图,是我对流批一体知识体系的理解。它涵盖了从底层存储到上层调度的主要模块,也是咱们这门课后续要展开的内容。

流批一体知识体系 统一调度层(任务调度在流批一体中的实践) 统一计算引擎层(Flink / Spark Streaming + Batch) 统一存储层(分层存储:消息队列 + 对象存储 + 文件系统) 核心能力 统一 SQL 语义 | 状态管理 | 迟到数据处理 | Exactly-Once 语义 容错与恢复 | 资源弹性伸缩 | 数据血缘追踪 架构模式:Lambda 架构 ↔ Kappa 架构 ↔ 混合架构 本课程核心 调度如何统一管理

从这张图你能看到,流批一体不是某一个层面的技术,而是从调度、计算、存储到架构模式的系统性工程。咱们这门课聚焦在最上层——统一调度层,但理解它需要先搞清楚下面几层的能力和约束。