Flink 流批一体架构设计与企业落地实践

解析Flink作为流批一体引擎的SQL层统一与Iceberg存储层设计从Lambda到Kappa的演进路径

袋鼠云
袋鼠云
数据治理 经营分析

同时维护 Spark 离线链路和 Flink 实时链路,是很多企业大数据团队的真实痛点:两套代码、两套调度、两套监控,口径还经常对不上。Flink 流批一体架构设计的核心目标就是用一套引擎、一套代码同时处理批式和流式数据,从根源上消除双链路带来的维护成本和数据不一致问题。本文结合字节跳动和袋鼠云的实践案例,解析 Flink SQL 层统一、Iceberg 存储层设计,以及从 Lambda 到 Kappa 架构的演进路径。

从 Lambda 到流批一体:为什么必须变

典型的 Lambda 架构把数据处理拆成两条独立链路。批式链路用 Spark 读取历史数据,经过 ETL 后写入下游存储,延迟在小时级;流式链路用 Flink 消费消息队列,实时处理后写入另一个存储,延迟在秒级。两条链路各自独立运行,服务于同一个下游应用。

字节跳动每天处理约 70PB 增量数据,拥有超过 400 万核流式计算资源和 500 万核批式计算资源。在这种规模下,Lambda 架构的弊端被放大到极致。第一,计算不同源:批式用 Spark、流式用 Flink,两套代码无法复用,工程师需要同时掌握两套引擎,维护成本极高。第二,数据不一致:同一条业务指标,离线链路和实时链路的计算结果经常对不上,业务方不知道该信哪个。第三,资源浪费:流式计算的高峰在白天,批式计算通常在凌晨执行,但如果两套资源不能混合调度,就无法实现错峰使用。

这些问题不是字节跳动独有的。凡是有实时计算需求的企业,在数据量增长到一定规模后都会遇到类似的困境。

Flink 流批一体的第一个关键设计是在 SQL 层实现统一。Flink 本身是一个面向有限流和无限流的有状态计算框架,批处理只是流处理的一种特例——用时间窗口把无限流切分成有限流,就得到了批处理。这种设计从底层引擎到上层 API 天然支持流批一体。

在实践中,推荐的做法是用 Flink SQL 而非 DataStream API 来实现流批一体。Flink SQL 提供了声明式的 SQL 接口,同一份 SQL 代码既能处理无界数据流(实时场景),也能处理有界数据集(离线场景),只需要在提交任务时指定执行模式。字节跳动的推荐系统正是这样做的:特征计算的 Flink SQL 代码既用于实时特征提取,也用于离线特征回溯,保证了流批计算口径的完全一致。

袋鼠云在其大数据开发平台 BatchWorks 和 StreamWorks 的统一开发框架中,也采用了类似的思路。用户在统一的 SQL 开发环境中编写 Flink SQL,平台自动判断任务类型并分配对应的执行模式,用户不需要关心底层是流式还是批式执行。这种"写一次、跑两次"的模式大幅降低了双链路维护成本。

采用 Flink SQL 实现流批一体后,核心收益有三个:代码复用带来的开发成本降低、口径一致带来的数据质量提升、以及流批共用引擎带来的运维简化。

实时开发 StreamWorks

覆盖采集、开发、运维全链路的云原生一站式实时数据开发平台

了解产品

Iceberg 存储层:流批一体的另一半拼图

计算层统一了,存储层也必须跟上。如果流式结果写入 Kafka,批式结果写入 Hive,数据依然分散在两个系统中,一致性问题并没有真正解决。

Apache Iceberg 是当前流批一体存储层的主流选择。它是一个开放的表格式,在对象存储或 HDFS 之上提供 Schema 演化、ACID 事务、快照隔离、时间旅行等能力。关键是 Iceberg 能同时支持流式写入和批量读写:Flink 可以将实时处理结果以 Upsert 方式写入 Iceberg 表,Spark 也可以对同一张表进行批量查询和回溯分析。

字节跳动在推荐系统中的实践是:用户行为数据通过自研消息队列 BMQ 实时传输到 Flink,经 Flink SQL 处理后以 Upsert 方式写入 Iceberg 表,底层存储使用自研的 CloudFS 大数据文件存储。Iceberg 提供了 ACID 保证和快照功能,支持并发读写,同时通过 Arrow 向量化数据传输降低了特征训练的 CPU 消耗(降低 13%)和网络 IO(降低 40%)。特征存储成本整体降低了 40% 以上。

Iceberg 的小文件 Compaction 机制也很重要。流式写入会产生大量小文件,如果不做合并,后续批量查询的性能会急剧下降。Iceberg 的自动 Compaction 可以在后台将小文件合并成大文件,保持查询性能。

数据治理

统一标准、质量、安全与资产管理,沉淀高质量数据集,支撑经营决策、监管合规与 AI 应用。

了解解决方案

从 Lambda 到 Kappa 的演进路径

流批一体并不意味着必须一步到位地从 Lambda 跳到 Kappa。更务实的路径是分三步走。

第一步:存储统一。 无论现有架构是 Lambda 还是其他形态,先将存储层统一到 Iceberg。离线链路和实时链路的结果都写入同一张 Iceberg 表,实现存储同源。这一步改动最小、收益最直接——至少解决了数据不一致的问题。

第二步:计算收敛。 逐步将 Spark 离线任务迁移到 Flink SQL 上,用同一套 SQL 同时处理流式和批式数据。这个过程可以按业务域分批推进,先迁成熟度高的域,保留对 Spark 有强依赖的场景(如大规模机器学习特征工程)。袋鼠云的统一开发平台在这个阶段提供了关键支撑:通过标准化的 Flink SQL 模板和自动化任务调度,降低了迁移的技术门槛。

第三步:架构精简。 当绝大部分任务都收敛到 Flink + Iceberg 后,Lambda 架构中的离线链路可以逐步退役,整个架构演进为 Kappa 架构——单一的流处理引擎处理所有数据,历史数据通过重放 Iceberg 快照来实现回溯。

常见陷阱与应对

流批一体落地过程中有几个高频陷阱。第一,低估状态管理的复杂度。Flink 的流批一体依赖强大的状态后端(如 RocksDB),如果状态大小超出预期,会导致 Checkpoint 超时和性能下降。建议在上线前进行充分的状态大小评估。第二,Iceberg 的 Schema 演化要谨慎。频繁修改 Schema 会导致历史数据兼容性问题,建议在项目初期就设计好相对稳定的 Schema。第三,不要试图用流批一体替代所有场景。大规模的机器学习训练、复杂的图计算等场景,Spark 和 Ray 仍有独特优势,流批一体架构应该与这些引擎互补共存。

流批一体不是终点,而是大数据架构从碎片化走向统一的关键一步。选对引擎、选对存储、分步推进,才是落地的正确姿势。

开启Data+AI 之旅

填写表单,获取专属解决方案

400-002-1024

工作日 9:00-18:00

关注公众号

获取最新产品动态与技术干货

关注公众号

企业微信

扫码添加企业微信