Flink中StateBackend(工作状态)与Checkpoint(状态快照)的关系

State Backends

由 Flink 管理的 keyed state 是一种分片的键/值存储,每个 keyed state 的工作副本都保存在负责该键的 taskmanager 本地中。另外,Operator state 也保存在机器节点本地。Flink 定期获取所有状态的快照,并将这些快照复制到持久化的位置,例如分布式文件系统。

如果发生故障,Flink 可以恢复应用程序的完整状态并继续处理,就如同没有出现过异常。

Flink 管理的状态存储在 state backend 中。Flink 有两种 state backend 的实现:

  • 一种基于 RocksDB 内嵌 key/value 存储将其工作状态保存在磁盘上的,将其状态快照持久化到(分布式)文件系统;
  • 另一种基于堆的 state backend,将其工作状态保存在 Java 的堆内存中。这种基于堆的 state backend 有两种类型:
    • FsStateBackend,将其状态快照持久化到(分布式)文件系统;
    • MemoryStateBackend,它使用 JobManager 的堆保存状态快照。

当使用基于堆的 state backend 保存状态时,访问和更新涉及在堆上读写对象。但是对于保存在 RocksDBStateBackend 中的对象,访问和更新涉及序列化和反序列化,所以会有更大的开销。但 RocksDB 的状态量仅受本地磁盘大小的限制。还要注意,只有 RocksDBStateBackend 能够进行增量快照,这对于具有大量变化缓慢状态的应用程序来说是大有裨益的。

所有这些 state backends 都能够异步执行快照,这意味着它们可以在不妨碍正在进行的流处理的情况下执行快照。

Checkpoint

Flink 定期对每个算子的所有状态进行持久化快照,并将这些快照复制到更持久的地方,例如分布式文件系统。 如果发生故障,Flink 可以恢复应用程序的完整状态并恢复处理,就好像没有出现任何问题一样。

这些快照的存储位置是通过作业_checkpoint storage_定义的。 有两种可用检查点存储实现:一种持久保存其状态快照 到一个分布式文件系统,另一种是使用 JobManager 的堆。

Flink不同版本StateBackend(状态)与Checkpoint Storage(快照) 关系

在Flink1.14之前StateBackend与Checkpoint Storage 耦合在一起,但在Flink1.14之后把StateBackend与Checkpoint Storage 实现了解耦,使逻辑更加清晰。

Flink1.14之前

  • 基于 RocksDB state backend,状态快照持久化到(分布式)文件系统;
java 复制代码
StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
env.setStateBackend(new RocksDBStateBackend("hdfs://namenode:8020/data/rocksdb/ck", true));//true: 增量checkpoint; false:全量checkpoint
env.setStateBackend(new RocksDBStateBackend("file:///data/rocksdb/ck", true));//本地文件系统
  • 基于heap state backend,状态快照持久化到(分布式)文件系统;
java 复制代码
StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
env.setStateBackend(new FsStateBackend("hdfs://namenode:8020/data/fs/ck"));//远程分布式文件系统
env.setStateBackend(new FsStateBackend("file:///data/fs/ck"));//本地文件系统
  • 基于heap state backend,使用 JobManager 的堆保存状态快照。
java 复制代码
StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
env.setStateBackend(new MemoryStateBackend());

Flink1.14之后(推荐使用)

  • 基于 RocksDB state backend,状态快照持久化到(分布式)文件系统;
java 复制代码
StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
env.setStateBackend(new EmbeddedRocksDBStateBackend(true));//true: 增量checkpoint; false:全量checkpoint
env.getCheckpointConfig().setCheckpointStorage("hdfs://namenode:8020/data/rocksdb/ck");//远程分布式文件系统
env.getCheckpointConfig().setCheckpointStorage("file:///data/rocksdb/ck");//本地文件系统

flink-conf.yaml配置:

yaml 复制代码
 state.backend: rocksdb
 state.checkpoints.dir: hdfs:///checkpoints/
  • 基于heap state backend,状态快照持久化到(分布式)文件系统;
java 复制代码
StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
env.setStateBackend(new HashMapStateBackend());
env.getCheckpointConfig().setCheckpointStorage("hdfs://namenode:8020/data/fs/ck");//远程分布式文件系统
env.getCheckpointConfig().setCheckpointStorage("file:///data/fs/ck");//本地文件系统

flink-conf.yaml配置:

yaml 复制代码
 state.backend: hashmap
 state.checkpoints.dir: hdfs:///checkpoints/
  • 基于heap state backend,使用 JobManager 的堆保存状态快照。
java 复制代码
StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
env.setStateBackend(new HashMapStateBackend());
env.getCheckpointConfig().setCheckpointStorage(new JobManagerCheckpointStorage());

flink-conf.yaml配置:

yaml 复制代码
 state.backend: hashmap
 state.checkpoint-storage: jobmanager

总结

  • 默认情况下 checkpoint 是禁用的,需要手动开启: env.enableCheckpointing(long interval, CheckpointingMode mode)
  • 默认情况下,StateBackend是保持在 TaskManagers 的heap内存中,checkpoint 保存在 JobManager 的内存中。
  • 只有基于 RocksDB state backend的状态快照才支持增量checkpoint,基于heap的并不支持
  • Flink状态分为Keyed State和非keyed State:
    • Keyed State,可以使用RocksDB state backend和heap state backend。 所有支持的状态类型如下所示:

      • ValueState: 保存一个可以更新和检索的值(如上所述,每个值都对应到当前的输入数据的 key,因此算子接收到的每个 key 都可能对应一个值)。 这个值可以通过 update(T) 进行更新,通过 T value() 进行检索。

      • ListState: 保存一个元素的列表。可以往这个列表中追加数据,并在当前的列表上进行检索。可以通过 add(T) 或者 addAll(List) 进行添加元素,通过 Iterable get() 获得整个列表。还可以通过 update(List) 覆盖当前的列表。

      • ReducingState: 保存一个单值,表示添加到状态的所有值的聚合。接口与 ListState 类似,但使用 add(T) 增加元素,会使用提供的 ReduceFunction 进行聚合。

      • AggregatingState<IN, OUT>: 保留一个单值,表示添加到状态的所有值的聚合。和 ReducingState 相反的是, 聚合类型可能与 添加到状态的元素的类型不同。 接口与 ListState 类似,但使用 add(IN) 添加的元素会用指定的 AggregateFunction 进行聚合。

      • MapState<UK, UV>: 维护了一个映射列表。 你可以添加键值对到状态中,也可以获得反映当前所有映射的迭代器。使用 put(UK,UV) 或者 putAll(Map<UK,UV>) 添加映射。 使用 get(UK) 检索特定 key。 使用 entries(),keys() 和 values() 分别检索映射、键和值的可迭代视图。你还可以通过 isEmpty() 来判断是否包含任何键值对。

    • 非keyed State,不使用 RocksDB state backend,需要保存在内存中,包括:

      • 算子状态 (Operator State);
      • 广播状态 (Broadcast State),尤其需要考虑保证充足的内存;
      • 自定义 Operator State:CheckpointedFunction 接口提供了访问 non-keyed state 的方法,需要实现如下两个方法: void snapshotState(FunctionSnapshotContext context) throws Exception;

        void initializeState(FunctionInitializationContext context) throws Exception;

参考:

Fault Tolerance via State Snapshots

相关推荐
Yiyaoshujuku1 小时前
医院API接口,从医院真实世界数据HIS、LJS、EMR、PACS系统到医院药品流向数据....
大数据·前端·人工智能
STLearner1 小时前
AI论文速读 | 元认知监控赋能深度搜索:认知神经科学启发的分层优化框架
大数据·论文阅读·人工智能·python·深度学习·学习·机器学习
不一样的故事1261 小时前
抓重点、留弹性、重节奏
大数据·网络·人工智能·安全
大嘴皮猴儿1 小时前
跨境电商视频营销爆发时代:产品视频字幕翻译怎么做?跨马翻译实战全解析
大数据·人工智能·新媒体运营·自动翻译·教育电商
唐可盐2 小时前
【数据治理实践】第 10 期:数据时代的导航——数据目录
大数据·人工智能·数据治理·数字化转型·数据资产·数据资产入表
智链RFID3 小时前
当企业运营遇到瓶颈:RFID 为什么越来越被采用?
大数据·网络·人工智能·科技·rfid
Data-Miner3 小时前
50页可编辑PPT | 某大数据资产平台建设项目启动会材料
大数据
旺仔Sec3 小时前
2026江苏省职业院校技能大赛新一代信息技术赛道大数据应用开发项目样题
大数据·数据挖掘
wx_xkq12884 小时前
营销智脑V3企业级AI平台架构设计:优秘智能完成从单点工具到全链路生态布局
大数据·人工智能
2601_955363154 小时前
技术赋能B端拓客:号码核验行业的革新与价值重构,氪迹科技法人,股东号码筛选系统,阶梯式价格
大数据·人工智能·重构