Flink 2.0 的存算分离状态是什么?ForSt 解决了什么问题?

第 1096 题 约 3 分钟读完

本文目录
  1. 面试怎么回答
  2. 老架构的痛点:状态绑在本地盘上
  3. Flink 2.0 怎么做:远端存储变成状态的主存储
  4. 读远端会不会很慢?异步状态访问
  5. 什么时候值得用

面试怎么回答

Flink 1.x 的大状态放在 TaskManager 本地的 RocksDB 里,远端只有 Checkpoint 备份,所以本地盘要够大、Checkpoint 上传有尖刺、扩缩容和恢复时要先把状态下载回来,状态越大越慢。Flink 2.0 做了存算分离,新的状态后端 ForSt 把状态的主存储放到 S3、HDFS 这类远端文件系统,本地盘只做缓存,Checkpoint 只记录文件引用,恢复和改并行度不用再整份下载。远端读取延迟高,所以配套了异步状态访问,同一个 key 保证有序、不同 key 并发,把延迟藏起来。它适合 TB 级状态、经常扩缩容、跑在云上和 K8s 上的作业;状态小、延迟极敏感的作业继续用本地状态后端就行。

先把这段讲顺;面试官追问时,再展开下面的原理和细节。

详细讲解

Flink 2.0 最大的变化之一是「存算分离的状态管理」(Disaggregated State Management)。面试官问这个,是想看你知不知道大状态作业在老架构下到底痛在哪,以及新架构是怎么解决的。

老架构的痛点:状态绑在本地盘上

Flink 1.x 用 RocksDB 做大状态时,状态的「主副本」在 TaskManager 的本地磁盘上,远端存储(HDFS / S3)里只有 Checkpoint 的备份。这带来几个问题:

  • 本地盘要够大:状态有几个 TB,每台机器就得挂足够的本地盘,容器化和云上部署很别扭。
  • Checkpoint 有尖刺:每次 Checkpoint 都要把本地新增的 SST 文件上传到远端,状态大时网络和磁盘 IO 突然飙高。
  • 扩缩容和恢复慢:作业重启或改并行度时,要先把状态从远端下载回本地才能开始处理,状态越大等得越久,几十分钟都很常见。

Flink 2.0 怎么做:远端存储变成状态的主存储

Flink 2.0 引入了新的状态后端 ForSt(For Streaming,基于 RocksDB 改造)。核心思路是:

  1. 状态直接写在远端文件系统(S3、OSS、HDFS),本地磁盘只做缓存,不再是状态的唯一归宿。
  2. Checkpoint 变轻:状态文件本来就在远端,Checkpoint 主要是记录文件引用,不用大量上传。
  3. 恢复和扩缩容变快:新的 TaskManager 不用先把全部状态下载到本地,直接读远端文件就能开始处理,热数据再慢慢进本地缓存。

读远端会不会很慢?异步状态访问

状态放远端,单次读取的延迟肯定比本地盘高。如果还是「读一条状态 → 等结果 → 处理下一条」的同步模型,吞吐会掉得很厉害。

所以 Flink 2.0 配套引入了异步状态访问(State API V2):算子发起状态读取后不阻塞,先去处理别的记录,结果回来再继续。框架保证同一个 key 的记录仍然按顺序处理,不同 key 之间可以并发,这样把远端访问的延迟藏起来。

要注意,想吃到这个红利,算子要用新的异步状态 API;Flink SQL 的部分算子已经改造好了,DataStream 作业需要自己迁移。

什么时候值得用

  • 状态很大(TB 级)、经常扩缩容或重启恢复慢的作业;
  • 在 Kubernetes、云上部署,不想给每台机器配大本地盘;
  • 状态小、对单条延迟极其敏感的作业,继续用本地 RocksDB 或 HashMap 状态后端就行,没必要换。