1. 流批一体概述

大家好,我是老赵。做数据架构十几年了,今天咱们聊聊流批一体。

说实话,这个概念的提出,背后是无数工程师的血泪史。我自己就经历过那种「白天写批处理,晚上改流处理」的崩溃日子。嗯,咱们从头说起。

1.1 流批一体到底是什么?

流批一体,说白了就是一套技术栈,同时搞定实时流处理和离线批处理。

你想想看,传统做法是两套系统:

  • 批处理:跑 T+1 的离线任务,数据准,但慢
  • 流处理:做秒级实时计算,快,但数据可能不准

流批一体想干的事很简单——同一份代码,同一个引擎,既能跑批,也能跑流。

核心思想:批处理是流处理的特殊情况。当流处理的时间窗口无限大时,它就是批处理。

我在项目中遇到过不少团队,流批分离时,批处理用 Spark,流处理用 Flink。两套代码,两套运维,两套数据口径。对不上账是常事。

1.2 Lambda 架构:曾经的王者

Lambda 架构是 Nathan Marz 提出的。它把数据链路拆成三层:

层级 职责 典型技术
批处理层 全量数据计算,保证准确性 Hadoop MapReduce, Spark Batch
流处理层 实时数据计算,保证低延迟 Storm, Flink Streaming
服务层 合并批和流的结果,对外提供服务 HBase, Cassandra, Elasticsearch

看起来挺完美对吧?但实际用起来,问题不少。

我曾经踩过的坑:Lambda 架构最大的痛点是「两套代码」。批处理和流处理逻辑必须保持一致,但实现方式完全不同。改一个业务逻辑,要改两处代码,还要保证结果一致。我见过一个团队,因为批流口径不一致,对账对了一个月。

另外,服务层的合并逻辑也很头疼。批结果和流结果怎么 merge?时间戳对齐?还是业务主键去重?每个场景都不一样。

1.3 Kappa 架构:更简洁的替代方案

Kappa 架构是 Jay Kreps 提出的。它的思路很直接——只用一套流处理引擎。

怎么做到的?核心就两点:

  1. 所有数据都是流:包括历史数据。把历史数据重新灌入流引擎,当作「慢速流」处理
  2. 重放机制:需要重新计算时,从消息队列的 offset 位置重放数据

我的建议:Kappa 架构更适合数据量中等、业务逻辑相对简单的场景。如果数据量极大(PB 级),全量重放的成本会很高。

Kappa 架构的优点是显而易见的:

  • 一套代码,一套运维
  • 数据口径天然一致
  • 架构更简洁

但缺点也有:

  • 对消息队列的存储能力要求高(要能存下全量历史数据)
  • 重放大规模历史数据时,性能可能不如批处理

1.4 Lambda vs Kappa:怎么选?

我直接给结论:

对比维度 Lambda 架构 Kappa 架构
代码维护 两套代码,维护成本高 一套代码,维护成本低
数据一致性 批流合并,容易出偏差 天然一致
历史重算 批处理层直接重算,效率高 流重放,数据量大时慢
实时性 流处理层保证低延迟 流处理,延迟同样低
架构复杂度 高,三层架构 低,单层架构
适用场景 大厂、复杂业务、数据量极大 中小规模、业务逻辑清晰

我个人习惯是:能用 Kappa 就别用 Lambda。除非你的数据量真的到了 PB 级,或者业务逻辑复杂到必须用批处理来兜底。

1.5 流批一体的核心价值

说了这么多,流批一体到底能带来什么?我总结了三句话:

  1. 开发效率翻倍:一套代码搞定批和流,不用再维护两套逻辑
  2. 数据口径统一:批和流的结果天然一致,不再需要对账
  3. 运维成本降低:一套集群,一套监控,一套告警

你想想看,以前一个实时数据需求,流处理写一遍,批处理再写一遍,测试两遍,上线两遍。现在一次搞定。这省下来的时间,够你喝多少杯咖啡?

当然,流批一体也不是银弹。它要求你的技术栈必须统一,比如都用 Flink,或者都用 Spark Structured Streaming。这对团队的技术选型提出了更高要求。

下面这张图,是我自己画的流批一体核心逻辑图,你看一眼就明白了:

流批一体核心架构逻辑 数据源 消息队列 (Kafka/Pulsar) 流批一体引擎 (Flink/Spark) 同一份代码,两种运行模式 实时流输出 离线批输出 统一服务层 (数据口径一致) 核心逻辑:批处理 = 流处理的时间窗口无限大,同一份代码在不同模式下运行

你看,从数据源到消息队列,再到流批一体引擎,最后统一输出。整个链路清晰明了。

好了,这一章就到这里。流批一体的概念、Lambda 和 Kappa 的对比、核心价值,我都讲清楚了。后面咱们会深入具体的目录管理实战,到时候你会看到这些理论是怎么落地的。