You need to enable JavaScript to run this app.
文档中心
流式计算 Flink版

流式计算 Flink版

复制全文
下载 pdf
性能调优
Flink SQL 状态和磁盘调优
复制全文
下载 pdf
Flink SQL 状态和磁盘调优

1.1 运行架构

火山引擎 Flink 基于 Kubernetes 容器化部署,核心组件包括:

  • JobManager(JM):负责作业调度、Checkpoint 协调、元数据管理
  • TaskManager(TM):负责实际数据处理,承载 Task 运行及状态管理

Image

1.2 默认磁盘空间

火山引擎 Flink 每个 TaskManager 容器的默认磁盘配置如下:

配置项

默认值

说明

容器磁盘总量

40 GB

每个 TM Pod 的本地磁盘空间

日志磁盘容量

5 GB

包含控制台输出日志/Flink 作业日志/ state 日志

Flink 状态/依赖 Jar 磁盘容量

20 GB

包含 Flink 状态/用户依赖 Jar

State Backend

RocksDB

状态数据存储在本地磁盘

1.3 磁盘占用方式

TaskManager 本地磁盘被以下几个部分占用:

  1. RocksDB 状态数据:Flink 使用 RocksDB 作为状态后端,所有 Keyed State(如 ValueState、MapState、ListState)都会写入 RocksDB 的 SST 文件,占据磁盘空间。
  2. RocksDB WAL 日志:Write-Ahead Log 用于保证数据持久性。
  3. Checkpoint 临时文件:Checkpoint 过程中会在本地生成临时快照文件。
  4. 日志文件:TaskManager 运行日志。
  5. Shuffle 数据:算子间数据交换的临时缓冲文件。
  6. SinkMaterializer 状态:SQL 任务中 SinkMaterializer 算子维护的物化状态。

2.1 状态(State)占用

在 Flink SQL 同步任务中,以下场景会产生大量状态数据:

场景

状态类型

说明

JOIN 操作

MapState

双流 JOIN 需保存两侧数据,等待匹配

GROUP BY 聚合

ValueState/MapState

维护聚合中间结果

DISTINCT 去重

MapState

需记录已出现的 Key

Temporal Join

ValueState

维护维表最新状态

Window 窗口

ListState

窗口内数据缓存

Deduplicate

ValueState

去重标记状态

Lookup Join(缓存模式)

MapState

维表缓存

注意

状态大小与数据量、Key 的基数直接相关。当 Key 基数很高(如用户级别的去重、全量 JOIN)时,状态可能增长到数十 GB,远超容器磁盘容量。

2.2 SinkMaterializer 占用

SinkMaterializer 是 Flink SQL 中一个隐含的算子,在以下情况会自动插入:

  • Sink 表的主键(Primary Key)与上游输出的 Key 不一致时:SinkMaterializer 需要物化上游数据,以生成正确的 Upsert 语义
  • Sink 不支持 Delete/Update 消息时:需要物化后转换为 Insert 消息

SinkMaterializer 会为每一条主键维护一份完整的行数据状态。当数据量较大时,物化状态会快速膨胀,导致磁盘空间不足。
Image
另外,SinkMaterializer 相当于把所有的变更缓存在本地,如果状态 TTL 过期,可能会导致 -D +U 等事件丢失。尽量避免引入此算子,保持上下游 key 能够一一对应。
诊断方法:通过 Flink Web UI 查看作业拓扑,如果 Sink 前存在 SinkMaterializer 算子,说明该任务会额外占用磁盘空间用于物化状态。
如果确认不需要此算子,可以设置如下参数:

table.exec.sink.upsert-materialize: none

注意

此操作请慎重设置,确认下游不会存在乱序的问题。

3 磁盘不足问题解决方案

3.1 增加并发度与容器实例个数

原理

通过提高 Parallelism(并发度),增加 TaskManager 容器数量,将状态分散到更多容器中,从而降低单个容器的磁盘占用。

操作步骤

  1. 在作业配置中调大 parallelism.default 参数。
  2. 例如从 parallelism = 4 调整为 parallelism = 8
  3. 此时 TM 容器数量翻倍,每个容器承载的状态量减半。

适用场景

  • 数据量持续增长,单容器状态已接近磁盘上限。
  • 作业 Key 分布较均匀,扩并发后不会出现数据倾斜。

注意事项

  • 增加并发度会同比增加资源消耗(CPU + 内存)。
  • 需确认上下游 Source/Sink 支持对应的并发度。

3.2 保持并发不变缩小容器规格增多容器节点

原理

在不改变并发度的情况下,将每个 TaskManager 的 Slot 数减少(如从 2 调为 1),这样相同并发度下会启动更多的 TM 容器,每个容器承担更少的 Slot,状态分布更分散。

操作步骤

  1. 降低 taskmanager.numberOfTaskSlots 值(如从 2 降为 1)。
  2. 同时可适当减小单个 TM 的内存配置。
  3. 系统会自动启动更多 TM Pod 来满足 Slot 需求。

对比示例

方案

并发度

Slots/TM

TM 数量

单 TM 状态量

调整前

8

4

2

100%

调整后

8

2

4

50%

适用场景

  • 不希望增加总体并发度(避免影响数据一致性或产生过多小文件)。
  • 仅需解决单容器磁盘瓶颈问题。

3.3 降低 SQL 状态 TTL 控制状态规模

原理

通过设置状态的 TTL(Time-To-Live),让过期数据自动清理,避免状态无限增长。

配置方式

方式一:通过界面配置

方式二:通过 SQL 配置

-- 在 Flink SQL 中设置状态 TTL
SET 'table.exec.state.ttl' = '24h';

常见配置建议

场景

推荐 TTL

说明

实时 Dashboard

1h ~ 6h

仅关注近期数据

日级别聚合

24h ~ 48h

保留一天+buffer

全量同步去重

视业务需求

需权衡数据完整性

JOIN 场景

根据迟到数据情况设置

过短可能丢失匹配

注意

TTL 设置过短可能导致数据不准确。例如在 JOIN 场景中,如果左表数据到达时右表对应记录已过期清除,将会导致 JOIN 结果丢失。需根据业务可容忍的延迟和数据完整性要求来合理设置。

3.4 使用自定义参数扩大容器磁盘空间

原理

直接增大 TaskManager 容器的磁盘配额,从资源层面上提供更多存储空间。

注意

当前暂不提供产品化的扩大磁盘容器空间的功能,需要用户发起工单联系产品团队,进行方案评估进行开放。

4 方案对比与选型建议

方案

优点

缺点

适用场景

增加并发度

状态分散、吞吐提升

资源消耗增加、可能产生小文件

数据量大、Key 均匀分布

减少 Slots/TM

不影响并发度

TM 数量增多、调度开销增加

仅磁盘瓶颈、不想改变并发

降低状态 TTL

直接减小状态量

可能影响数据准确性

对历史数据无强依赖

扩大容器磁盘

操作简单、无副作用

治标不治本、存储成本增加(问题:存储成本,和磁盘供应无法保障)

应急处理或状态确实需要大空间

推荐策略

  1. 优先评估下调 TTL 的可行性(参考章节 3.3 降低 SQL 状态 TTL 控制状态规模);
  2. 其次考虑提升并发能力或调整容器资源配比(参考章节3.1 增加并发度与容器实例个数3.2 保持并发不变缩小容器规格增多容器节点);
  3. 最后可通过扩容磁盘作为兜底方案(参考章节 3.4 使用自定义参数扩大容器磁盘空间)。
最近更新时间:2026.05.11 19:57:53
这个页面对您有帮助吗?
有用
有用
无用
无用