流批一体概述:从Lambda到Kappa,再到统一数据视图

聊流批一体之前,我想先问一个问题:为什么我们需要流批一体?

说白了,传统的数据架构把实时和离线分成了两套系统。实时走Flink、Storm,离线走Hive、Spark。两套代码、两套运维、两套数据口径。我在2018年帮一家电商公司做数据中台时,就遇到过这种尴尬——实时大屏显示GMV是1.2亿,离线报表跑出来却是1.15亿。业务方追着问:哪个是对的?

嗯,这就是流批分离的典型痛点。今天我们就来拆解一下,业界是怎么一步步走到流批一体这条路上的。

Lambda架构:两套系统并行

Lambda架构是Nathan Marz提出来的,核心思路很简单:用批处理保证准确性,用流处理保证低延迟。数据同时走两条路——

  • 批处理层:全量数据重新计算,结果准确但延迟高
  • 流处理层:实时增量计算,延迟低但可能不精确
  • 服务层:合并两边的结果,对外提供服务

听起来挺合理对吧?但我在实际项目中踩过坑。有一次做用户画像标签,实时层算出的“近7天活跃天数”和离线层差了2天。查了半天,发现是实时层用的时间窗口是滑动窗口,离线层用的是固定日历周。口径对不上,合并层根本没法做。

我曾经踩过的坑:Lambda架构最大的问题不是技术实现,而是逻辑一致性。两套代码各自实现同一套业务逻辑,很难保证完全对齐。一旦出现偏差,排查成本极高。

Lambda架构的另一个痛点——维护两套代码。批处理写一套Spark SQL,流处理写一套Flink SQL。改一个业务逻辑,两边都得改。我见过一个团队,因为实时和离线代码不同步,线上跑了三个月才发现口径偏了5%。

Kappa架构:只保留流处理

Kappa架构是Jay Kreps提出来的。他的想法很直接:既然流处理也能做全量重算,为什么还要保留批处理?

核心思路:所有数据都走流处理管道。需要重算时,从Kafka等消息队列的起点重新消费数据。这样只有一套代码,口径天然一致。

听起来很完美?但实际落地时,我遇到过几个问题——

  • 历史数据回溯性能:Kafka的存储是有限的,默认只保留7天。要回溯更早的数据,得从HDFS或对象存储里重新灌入。这个过程如果数据量大,跑起来很慢。
  • 状态管理复杂度:流处理的状态后端(比如RocksDB)在数据量达到TB级别时,性能会急剧下降。我有个项目,状态大小到了1.5TB,Checkpoint经常超时。
  • Exactly-Once语义:虽然Flink支持端到端的Exactly-Once,但下游系统(比如HBase、Elasticsearch)不一定支持。重算时容易产生重复数据。
我的建议:Kappa架构更适合数据量可控、状态大小在百GB以内的场景。如果历史数据超过PB级,或者状态超过TB级,Lambda架构可能更现实。

流批一体的核心挑战

不管是Lambda还是Kappa,流批一体要解决的核心问题其实就三个——

挑战 具体表现 我的经验
语义一致性 实时和离线计算结果不同 口径对齐是最容易被忽视的环节
存储统一 实时用Kafka,离线用HDFS 数据来回拷贝,浪费存储和带宽
计算引擎统一 Flink写一套,Spark写一套 维护成本翻倍,bug概率翻倍

为什么会这样?我分析下来,根本原因在于流和批在抽象层面存在差异——

  • 时间语义:流处理关注事件时间、处理时间;批处理关注分区时间、快照时间
  • 数据触发:流处理是连续触发;批处理是定时触发
  • 容错机制:流处理靠Checkpoint/Savepoint;批处理靠重试/重跑

你想想看,如果底层抽象都不一样,上层怎么统一?所以流批一体的第一步,不是选引擎,而是统一数据模型。

统一数据视图:为什么需要它?

统一数据视图,说白了就是让实时数据和离线数据对外呈现为同一张表。业务方不需要关心数据是实时来的还是离线来的,只需要查一个视图。

我在一个金融风控项目里做过类似的事情。业务方要查“用户近30天交易总额”,这个指标既有实时增量(今天发生的交易),又有离线全量(历史交易)。我们做了个统一视图,底层自动合并实时流和离线表,对外暴露一个接口。业务方说:终于不用再问“实时准还是离线准”了。

统一数据视图的核心能力:
  • 透明访问:用户不需要知道数据来源
  • 自动合并:实时数据和离线数据按规则合并
  • 一致性保证:最终一致性或强一致性,按需选择
  • 时效性感知:数据是秒级、分钟级还是小时级,视图层能感知

实现统一数据视图,通常有两种方式——

  • 逻辑视图:通过SQL引擎(如Presto、Trino)做联邦查询,实时表和离线表在查询时合并。优点是灵活,缺点是查询延迟高。
  • 物理视图:通过ETL将实时数据写入离线存储,或者反过来。优点是查询快,缺点是数据冗余。

我个人更倾向于逻辑视图+缓存的组合。热数据走缓存,冷数据走联邦查询。既保证了查询性能,又避免了数据冗余。

流批一体的架构演进图

下面这张图展示了从Lambda到Kappa,再到统一数据视图的演进路径——

流批一体架构演进路径 Lambda 架构 批处理层 流处理层 服务层 核心问题 两套代码口径不一致 维护成本高 排查问题困难 Kappa 架构 统一流处理管道 新问题 历史回溯性能瓶颈 状态管理复杂度高 统一数据视图 透明访问 自动合并 一致性保证 时效性感知 数据契约是统一数据视图的“粘合剂” 定义实时与离线之间的数据格式、口径、时效性约束

从这张图可以看得很清楚——数据契约在统一数据视图里扮演着“粘合剂”的角色。它定义了实时数据和离线数据之间的格式、口径、时效性约束。没有数据契约,统一视图就是空中楼阁。

小结

这一章我们聊了Lambda和Kappa两种架构的优缺点,也分析了流批一体的核心挑战。我个人认为,架构选型没有银弹。Lambda架构适合数据量大、对准确性要求高的场景;Kappa架构适合数据量可控、追求代码统一的场景。而统一数据视图,是解决“实时离线两张皮”问题的关键思路。