Flink 2.0 新特性解读:物化表与流批统一
从流批统一与湖仓集成视角解读 Flink 2.0 物化表、自适应批执行等特性对实时数仓开发范式的影响
Flink 2.0 的定位不是又一个大版本,而是自 1.0 之后近十年来的首次主版本升级:它在 2025 年 3 月 24 日发布,核心变化可以概括为三条主线——用物化表把流批两套开发范式统一成"一张表",用自适应批执行让批作业按运行时数据自动优化,用与 Paimon 的深度集成把实时数仓推进到流式湖仓;同时它清掉了一批历史包袱(DataSet API、旧的 Source/Sink API、per-job 部署模式),这意味着升级不是换个 jar 那么简单。是否值得升级、怎么迁移,取决于你现在用到了哪些 API 和 Connector。
版本定位与关键变化概览
这次发布由 165 位贡献者完成 25 个 FLIP 与 369 个 issue,是 Flink 历史上第一次真正意义的"架构换代"。与业务直接相关的关键变化:
- 物化表(Materialized Table):流批统一的声明式表抽象,2.0 中达到生产可用。
- 自适应批执行(Adaptive Batch Execution):新增自适应广播连接与自动 Join 倾斜优化。
- 存算分离状态管理:新增 ForSt 状态后端,把状态存储到分布式文件系统,配合异步状态访问降低容器化环境对本地盘的依赖。
- 流式湖仓:与 Paimon 深度集成,包括嵌套投影下推、按分桶对齐的 Lookup Join 优化、SQL 化维护操作。
- 破坏性变更:DataSet API、Scala DataStream/DataSet API、SourceFunction/SinkFunction/Sink V1 被移除;Java 8 不再支持(最低 Java 11,默认推荐 Java 17,官方支持 Java 21);
flink-conf.yaml改为config.yaml;per-job 部署模式移除,改用 Application 模式;1.x 与 2.x 之间不保证状态兼容。
上述破坏性变更的完整清单以官方发布说明与 Release Notes 为准。
物化表:从"两套代码"到"一张表"
物化表解决的是实时数仓开发中最痛的问题:同一份业务逻辑,批任务和流任务往往要各写一遍,还要手动维护调度关系。物化表的思路是让用户只声明"我要什么数据、数据要多新",由系统决定用流作业还是批作业去刷新。在 Flink 2.0 中,物化表支持查询与 Schema 的在线修改,业务逻辑调整后不需要重新处理历史数据,这是它从实验特性走向生产可用的关键一步;同时刷新作业可以提交到 YARN 或 Kubernetes 上运行,能纳入现有的资源管理体系中。
一个典型的声明方式(语法示意):
CREATE MATERIALIZED TABLE dwd_order_agg
PARTITIONED BY (dt)
FRESHNESS = INTERVAL '10' MINUTE
AS SELECT user_id, count(*) AS order_cnt, sum(amount) AS amount
FROM ods_order
GROUP BY user_id;FRESHNESS 声明数据新鲜度,系统据此决定以流模式持续刷新,还是以批模式周期性刷新。开发者的心智模型从"启动一个 Flink 作业"变成"维护一张表",调度、重启、补偿这些事交给平台层。代价是:物化表目前把 Paimon 作为首个也是唯一支持的 Catalog,如果你的存储不是 Paimon,就需要先评估存储侧改造。
自适应批执行:让批作业自己决定怎么跑
批作业优化难在"计划时不知道数据长什么样"。Flink 2.0 的自适应批执行把优化推迟到运行时:动态分区裁剪、Runtime Filter、按数据量自动决定并行度这些能力在之前的版本已经具备,2.0 新增的两个优化是:
- 自适应广播连接(Adaptive Broadcast Join):编译期很难准确估算 Join 一侧的输入大小,系统在运行时拿到真实输入量后,如果满足广播条件就自动把 Shuffle Hash/Sort Merge 切换成 Broadcast Join,省掉大 shuffle 和排序。
- 自动 Join 倾斜优化(Adaptive Skewed Join):利用运行时统计信息,把数据量严重不均的 Join 分区动态拆分,同时保证 Join 结果语义完整,缓解长尾 Task。
官方以 10TB TPC-DS 做了对比:相对 1.20,在 ANALYZE TABLE 生成统计信息后整体性能提升 8%,没有统计信息时提升 16%——说明统计信息缺失时收益反而更大,对"没时间做统计信息治理"的团队尤其有价值。相关行为可以通过 table.optimizer.adaptive-broadcast-join.strategy、table.optimizer.skewed-join-optimization.strategy、execution.batch.adaptive.auto-parallelism.enabled 等配置控制。
实时开发 StreamWorks
覆盖采集、开发、运维全链路的云原生一站式实时数据开发平台
与 Paimon 的湖仓集成
Flink 2.0 在"流式湖仓"上的落地依赖 Paimon:物化表以 Paimon 作为默认存储;读 Paimon 数据时支持嵌套投影下推,复杂结构字段的 IO 明显减少;用 Paimon 做维表的 Lookup Join 会按 Paimon 的分桶对齐数据,显著降低每个查询任务需要拉取和缓存的数据量;compaction、snapshot 管理、branch/tag 维护等操作可以直接用 SQL CALL 语句执行。对已经在用"Flink + 数据湖"方案的团队,2.0 把这些零散的维护动作收进了 SQL,降低了运维脚本的维护成本。
存算分离状态管理:云原生场景的底牌
Flink 2.0 的另一条主线是状态管理架构调整:新增 ForSt 状态后端,把状态从本地盘搬到分布式文件系统(DFS),配合异步状态访问模型,解决容器环境本地盘受限、大状态作业扩缩容慢、Checkpoint 重等问题。官方在 Nexmark 基准上的数据是:对状态规模 1.2GB 到 4.8GB 的重 IO 查询,在 1GB 缓存下吞吐达到传统本地状态方案的 75% 到 120%;对 10MB 到 400MB 的小状态查询,性能与本地方案差距平均不超过 10%。启用入口是 table.exec.async-state.enabled,SQL 作业不需要改代码就能切换到异步状态访问。需要清醒认识的是:这不是零成本,远程状态访问引入额外网络延迟,缓存命中率低时性能会下降,建议先在测试集群用真实状态规模验证再上生产。
金融行业
围绕监管报送、风险监测、客户经营与总分协同,统一数据口径和安全管控,让金融经营与风控有数可依。
其他值得关注的新能力
- DataStream V2 API:提供新的底层 API 雏形,官方明确标注为实验阶段,不建议生产使用,但它是未来 API 演进的方向,新项目可以保持关注。
- SQL 语法增强:新增
QUALIFY子句(对窗口函数结果过滤)、C 风格转义字符串、表函数可直接写在FROM中,日常写 SQL 更顺手。 - SQL Gateway 支持 Application 模式:作为被移除的 per-job 模式的替代,多租户平台接入更顺。
- 序列化改进:集合类型(Map/List/Set)使用新的内置序列化器,并升级 Kryo 到 5.6,序列化开销更低。
升级迁移影响与兼容性
迁移前需要先盘点三类资产:
- API 层:还在用 DataSet API、Scala API 或旧 Source/Sink API 的作业必须重写,官方建议迁移到 DataStream API 或 Table API/SQL;自研 UDF/Connector 如果基于被移除的接口,也要一起改。
- Connector 层:官方在 2.0.0 发布后随即发布了适配新 API 的 Kafka、Paimon、JDBC、ElasticSearch 新版本 Connector,其余 Connector 计划在 2.3 之前陆续迁移完毕;第三方 Connector 要逐个确认是否支持 2.x。
- 运行环境层:Java 最低版本升到 11;
flink-conf.yaml不再识别,官方提供迁移工具转换成config.yaml;per-job 模式改为 Application 模式;1.x 的 state 与 2.x 不兼容,需要规划无状态重建或全量重算。
是否值得升级的决策建议
按以下顺序判断:如果你的作业大量使用 DataSet、Scala API 或老 Connector,先把迁移成本算清楚,升级窗口至少按"重写 + 回归"来排;如果你主要用 Table API/SQL 和官方新 Connector,且痛点集中在"流批两套开发"或"批作业长尾",2.0 的物化表和自适应批执行直接命中需求,值得尽快试点。落地时不要全量切换:先搭一套 2.0 集群,把一到两个低风险 SQL 作业迁过去,对比语义与性能,同时把"物化表 + Paimon"作为新开发项目的默认组合,确认稳定后再扩大范围;对无法迁移的存量作业保留在 1.x LTS 版本上,直到 Connector 生态跟进完成。


