Flink 2.x状态演进:理解解 1.x 与 2.x 状态存储机制

在大规模流处理领域,状态管理(State Management)始终是决定作业吞吐量、延迟和弹性伸缩能力的核心命脉。随着 Apache Flink 进入 2.x 时代,其状态架构迎来了自项目诞生以来最彻底的一次颠覆 ------ 从传统的存算一体(本地优先)架构,全面转向云原生的存算分离(Disaggregated State)架构。

本文将深度剖析 Flink 1.x(以 RocksDB 为核心)与 Flink 2.x(以 ForSt 为核心)在状态读写流程梳理,并通过全方位的横向对比,带你看清这场技术演进背后的设计。


在 Flink 1.x 中,当面对超大状态场景时,RocksDBStateBackend 是绝对的主力。它基于经典的单机 LSM-Tree(日志结构合并树) 架构。

1. 核心组件分布

  • 内存层: 包含 MemTable(内部基于跳表 SkipList 实现,用于接收并排序最新写入)和 Block Cache(缓存解压后的磁盘数据块,加速读)。
  • 磁盘层: 本地磁盘(NVMe/SSD)上分层存储的 SST(有序字符串表)文件。
  • 远端层: HDFS/S3 等分布式存储,在 1.x 中它仅作为 Checkpoint 的备份通路

2. 深度拆解:1.x 读写与快照流程

  • 写路径(同步阻塞): 当数据流经算子并触发 state.update(value) 时,数据通过 JNI(Java Native Interface)调用,直接写入本地 RocksDB 的内存 MemTable 中。
    MemTable写满后会变成 Immutable MemTable, 随后Flush 写入磁盘变成 SSTSorted String Table文件,当ck时将本地 文件上传到远端存储一般为hdfs

💡 核心内幕: Flink 在底层写入时默认调用了 setDisableWAL(true),因此完全关闭了 RocksDB 的单机预写日志(WAL)。Flink 宁愿在挂掉时通过"回滚上游 Kafka + 重放"来恢复内存,也绝不在运行时双写本地盘。

  • 刷盘与合并(Flush & Compaction):MemTable 满了,后台线程将其异步 dump 到本地磁盘生成 Level 0 层的 SST。随后触发的多层 SST 归并排序(Compaction),会疯狂抢占本地 TaskManager 的 CPU 和磁盘 I/O。

  • 增量检查点(Incremental Checkpoint): 触发 Checkpoint 时,RocksDB 在本地对 SST 文件创建 Hard Link(硬链接) (毫秒级阻塞),主线程随即释放。随后,Flink 的异步线程负责将本地新生成的 SST 文件物理复制并上传到远端 HDFS/S3

  • 读路径(多级查找): 算子调用 state.value(),线程会依次检索:内存 MemTable →\rightarrow→ Immutable MemTable →\rightarrow→ 内存 Block Cache →\rightarrow→ 本地磁盘 SST 文件(期间利用布隆过滤器避免盲目 I/O)。

3. 1.x 痛点

  • 单机磁盘瓶颈: 状态大小受限于本地磁盘容量,超大状态极易爆盘。
  • I/O 资源突刺: 后台 Compaction "肉搏"抢资源,导致作业吞吐频繁出现断崖式下跌。
  • 弹性伸缩极其缓慢: 作业扩缩容(Rescaling)时,新节点必须从远端全量下载 SST 文件并在本地重建 RocksDB 实例,TB 级状态恢复往往需要数十分钟甚至数小时。

为了将流处理推向真正的云原生化,Flink 2.x 彻底打破了"本地磁盘为主存储"的铁律,推出了专为流式存算分离定制的存储引擎 ------ ForSt (For Streaming)

1. 核心架构重构

在 2.x 中,远端分布式存储(DFS)直接晋升为 Primary Storage(主存储)。本地磁盘退化为高速只读缓存(Secondary Local Cache)。同时,全链路 API 进行了全异步化(Asynchronous State API)重写。

2. 深度拆解:2.x 全异步读写流程

  • 异步非阻塞写路径: 当算子调用全新的异步接口 state.asyncUpdate(value) 时,当前 Task 线程绝不等待,而是将请求封装为 StateRequest 丢入状态请求队列 后立即返回,继续处理下一条数据。
    后台的 AEC(异步执行控制器) 从队列提取请求,将相同 Key 空间的修改自动合并成大批次(Batch),直接写入 TaskManager 堆外内存的 ForSt MemTable 中(同样不写单机 WAL)。
  • 流水线乱序读路径:
    当调用 state.asyncValue() 时,Task 线程投递请求并拿到一个 Future,随即释放。AEC 异步线程接管请求,按照:内存 →\rightarrow→ 本地 SSD Cache →\rightarrow→ 远端 DFS 网络 RPC 的路径进行检索。
    网络数据返回后注入 Future 并触发回调。在等待远端 I/O 期间,算子可以疯狂处理后续数据,通过乱序执行模型(Out-of-Order Execution)和高并发请求,彻底掩盖了网络延迟。
  • 秒级轻量化 Checkpoint:
    因为 ForSt 在运行期间就已经把内存满溢的数据(SST)持续、直接地通过网络写向了远端 DFS。当 Checkpoint 栅栏(Barrier)到达时,AEC 只需要强行 Flush 队列中残存的请求,并等待远端落盘的 ACK。整个 Checkpoint 变成了纯粹的元数据标记,不再需要打包传输大文件,数秒内即可完成。

为了让你对这两代架构的演进有更直观的认识,我们将核心指标归纳为下表:

对比维度 Flink 1.x (RocksDB 存算一体) Flink 2.x (ForSt 存算分离) 带来的业务价值
状态主存储 (Primary) 本地磁盘 (Local SSD/NVMe) 远端分布式存储 (HDFS/S3/OSS) 状态容量突破单机限制,实现理论上的无限扩展
状态访问 API 模型 同步阻塞 (Synchronous & Blocking) 全异步乱序执行 (Asynchronous) 杜绝单条数据 I/O 卡死全局,用高并发吞吐掩盖网络延迟
单机 WAL (预写日志) 默认关闭 (setDisableWAL=true) 默认关闭 (依托 Flink 容错大盘) 避免流处理中的双重写入,榨干计算节点每一步的性能。
Checkpoint 耗时 较长 (需要在快照期同步/异步上传 SST 文件) 秒级 (运行时持续写,快照期仅对齐元数据) 极大减小了 Checkpoint 期间对线上业务造成的吞吐颠簸。
弹性伸缩与故障恢复 缓慢 (需全量下载状态文件并在本地重建实例) 极致快 (秒级拉起,Lazy Restore 按需异步加载) 大状态作业遭遇故障或扩缩容时,真正具备了秒级弹性能力
本地 I/O 资源稳定性 较差 (本地 Compaction 会引发严重的 I/O 突刺) 极好 (Compaction 算子卸载到远端或独立线程) TaskManager 算力极其纯净,消除了业务吞吐断崖下跌的顽疾。

四、 总结与升级建议

Flink 2.x 的存算分离状态架构,是流计算走向全面云原生、微服务化弹性的必经之路。它巧妙地利用"动态运行期全异步乱序,静态检查点强行冲刷确认"的设计,既享受了网络异步带来的超高吞吐,又死死守住了 Exactly-Once 的容错底线。

📢 升级避坑提示:

由于底层状态架构发生了基因级的重构,Flink 2.x 放弃了与 1.x 版本的状态(Savepoint/Checkpoint)直接二进制兼容 。此外,为了全面拥抱现代 Java 的并发和异步特性,Flink 2.x 彻底移除了对 Java 8 的支持,最低运行要求全面提升至 Java 11/17。在享受 2.x 极致弹性的红利前,务必提前做好技术栈的升级规划。

相关推荐
格子生意经1 小时前
GEO系统多引擎自适应算法实战解析
大数据·人工智能
2601_957190901 小时前
2026 沉浸式文旅投资风口|XR 黑暗乘骑市场前景、收益模型与落地指南
大数据·娱乐
Apache Flink2 小时前
从结构化到多模态:Apache Flink,多模态数据处理的流式底座
大数据·flink·apache
阿乔外贸日记2 小时前
快速了解东帝汶市场 基础经济概况汇总
大数据·人工智能
老白说数智化升级2 小时前
制造企业如何确定物流数智化建设的优先级?
大数据·人工智能·制造
xlrqx3 小时前
保定家电清洗培训全拆洗教涉及哪些核心要点与行业信息呢?
大数据·python
婉然从物5 小时前
Flink SQL 元数据持久化实战:从“每次重启表消失”到“Hive Metastore 永久存储”
hive·sql·flink
cc57250265311 小时前
高考志愿填报:大数据相关专业到底怎么选?
大数据·高考
本旺11 小时前
Elasticsearch 前缀匹配性能优化实战,附4种方式即执行计划判别
大数据·elasticsearch·性能优化