动手点关注 干货不迷路 👆
本文主要分享字节跳动在使用 Flink State 上的实践经验,内容包括 Flink State 相关实践以及部分字节内部在引擎上的优化,希望可以给 Flink 用户的开发及调优提供一些借鉴意义。
前言
Flink 作业需要借助 State 来完成聚合、Join 等有状态的计算任务,而 State 也一直都是作业调优的一个重点。目前 State 和 Checkpoint 已经在字节跳动内部被广泛使用,业务层面上 State 支持了数据集成、实时数仓、特征计算、样本拼接等典型场景;作业类型上支持了 Map-Only 类型的通道任务、ETL 任务,窗口聚合计算的指标统计任务,多流 Join 等存储数据明细的数据拼接任务。
以 WordCount 为例,假设我们需要统计 60 秒窗口内 Word 出现的次数:
select
word,
TUMBLE_START(eventtime, INTERVAL '60' SECOND) as t,
count(1)
from
words_stream
group by
TUMBLE(eventtime, INTERVAL '60' SECOND), word
每个还未触发的 60s 窗口内,每个 Word 对应的出现次数就是 Flink State,窗口每收到新的数据就会更新这个状态直到最后输出。为了防止作业失败,状态丢失,Flink 引入了分布式快照 Checkpoint 的概念,定期将 State 持久化到 Hdfs 上,如果作业 Failover,会从上一次成功的 checkpoint 恢复作业的状态(比如 kafka 的 offset,窗口内的统计数据等)。
在不同的业务场景下,用户往往需要对 State 和 Checkpoint 机制进行调优,来保证任务执行的性能和 Checkpoint 的稳定性。阅读下方内容之前,我们可以回忆一下,在使用 Flink State 时是否经常会面临以下问题:
某个状态算子出现处理瓶颈时,加资源也没法提高性能,不知该如何排查性能瓶颈
Checkpoint 经常出现执行效率慢,barrier 对齐时间长,频繁超时的现象
大作业的 Checkpoint 产生过多小文件,对线上 HDFS 产生小文件压力
RocksDB 的参数过多,使用的时候不知该怎么选择
作业扩缩容恢复时,恢复时间过长导致线上断流
State 及 RocksDB 相关概念介绍
State 分类

由于 OperatorState 背后的 StateBackend 只有 DefaultOperatorStateBackend,所以用户使用时通常指定的 FsStateBackend 和 RocksDBStateBackend 两种,实际上指定的是 KeyedState 对应的 StateBackend 类型:
FsStateBackend:DefaultOperatorStateBackend 和 HeapKeyedStateBackend 的组合
RocksDBStateBackend:DefaultOperatorStateBackend 和 RocksDBKeyedStateBackend 的组合
RocksDB 介绍
RocksDB 是嵌入式的 Key-Value 数据库,在 Flink 中被用作 RocksDBStateBackend 的底层存储。如下图所示,RocksDB 持久化的 SST 文件在本地文件系统上通过多个层级进行组织,不同层级之间会通过异步 Compaction 合并重复、过期和已删除的数据。在 RocksDB 的写入过程中,数据经过序列化后写入到 WriteBuffer,WriteBuffer 写满后转换为 Immutable Memtable 结构,再通过 RocksDB 的 flush 线程从内存 flush 到磁盘上;读取过程中,会先尝试从 WriteBuffer 和 Immutable Memtable 中读取数据,如果没有找到,则会查询 Block Cache,如果内存中都没有的话,则会按层级查找底层的 SST 文件,并将返回的结果所在的 Data Block 加载到 Block Cache,返回给上层应用。

RocksDBKeyedStateBackend 增量快照介绍
这里介绍一下大家在大状态场景下经常需要调优的 RocksDBKeyedStateBackend 增量快照。RocksDB 具有 append-only 特性,Flink 利用这一特性将两次 checkpoint 之间 SST 文件列表的差异作为状态增量上传到分布式文件系统上,并通过 JobMaster 中的 SharedStateRegistry 进行状态的注册和过期。

如上图所示,Task 进行了 3 次快照(假设作业设置保留最近 2 次 Checkpoint):
CP-1:R