Flink 2.0 的存算分离状态是什么?ForSt 解决了什么问题?
面试怎么回答
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 改造)。核心思路是:
- 状态直接写在远端文件系统(S3、OSS、HDFS),本地磁盘只做缓存,不再是状态的唯一归宿。
- Checkpoint 变轻:状态文件本来就在远端,Checkpoint 主要是记录文件引用,不用大量上传。
- 恢复和扩缩容变快:新的 TaskManager 不用先把全部状态下载到本地,直接读远端文件就能开始处理,热数据再慢慢进本地缓存。
读远端会不会很慢?异步状态访问
状态放远端,单次读取的延迟肯定比本地盘高。如果还是「读一条状态 → 等结果 → 处理下一条」的同步模型,吞吐会掉得很厉害。
所以 Flink 2.0 配套引入了异步状态访问(State API V2):算子发起状态读取后不阻塞,先去处理别的记录,结果回来再继续。框架保证同一个 key 的记录仍然按顺序处理,不同 key 之间可以并发,这样把远端访问的延迟藏起来。
要注意,想吃到这个红利,算子要用新的异步状态 API;Flink SQL 的部分算子已经改造好了,DataStream 作业需要自己迁移。
什么时候值得用
- 状态很大(TB 级)、经常扩缩容或重启恢复慢的作业;
- 在 Kubernetes、云上部署,不想给每台机器配大本地盘;
- 状态小、对单条延迟极其敏感的作业,继续用本地 RocksDB 或 HashMap 状态后端就行,没必要换。