Flink-Checkpoint

385 阅读5分钟

这是我参与8月更文挑战的第5天,活动详情查看:8月更文挑战

State Vs Checkpoint

State

  • 维护/存储的是某一个Operator的运行的状态/历史值,是维护在内存中
  • 一般指一个具体的Operator的状态(operator的状态表示一些算子在运行的过程中会产生的一些历史结果,如前面的maxBy底层会维护当前的最大值,也就是会维护一个keyedOperator,这个State里面存放就是maxBy这个Operator中的最大值)
  • State数据默认保存在Java的堆内存中/TaskManage节点的内存中
  • State可以被记录,在失败的情况下数据还可以恢复

Checkpoint

  • 某一时刻,Flink中所有的Operator的当前State的全局快照,一般存在磁盘上
  • 表示了一个Flink Job在一个特定时刻的一份全局状态快照,即包含了所有Operator的状态
  • 可以理解为Checkpoint是把State数据定时持久化存储了
  • 比如KafkaConsumer算子中维护的Offset状态,当任务重新恢复的时候可以从Checkpoint中获取

Checkpoint实现算法

  • Flink中的Checkpoint底层使用了Chandy-Lamport algorithm分布式快照算法可以保证数据的在分布式环境下的一致性
  • zhuanlan.zhihu.com/p/53482103
  • Chandy-Lamport algorithm算法的作者也是ZK中Paxos 一致性算法的作者
  • www.cnblogs.com/shenguanpu/…
  • Flink中使用Chandy-Lamport algorithm分布式快照算法取得了成功,后续Spark的StructuredStreaming也借鉴了该算法

Checkpoint执行流程

image.png

Checkpoint执行流程

  1. Flink的JobManager创建CheckpointCoordinator
  2. Coordinator向所有的SourceOperator发送Barrier栅栏(理解为执行Checkpoint的信号)
  3. SourceOperator接收到Barrier之后,暂停当前的操作(暂停的时间很短,因为后续的写快照是异步的),并制作State快照, 然后将自己的快照保存到指定的介质中(如HDFS), 一切 ok之后向Coordinator汇报并将Barrier发送给下游的其他Operator
  4. 其他的如TransformationOperator接收到Barrier,重复第2步,最后将Barrier发送给Sink
  5. Sink接收到Barrier之后重复第2步
  6. Coordinator接收到所有的Operator的执行ok的汇报结果,认为本次快照执行成功 【注意】:
  • 1.在往介质(如HDFS)中写入快照数据的时候是异步的(为了提高效率)
  • 2.分布式快照执行时的数据一致性由Chandy-Lamport algorithm分布式快照算法保证

状态后端

MemStateBackend

基于内存的状态管理器,了解,不推荐生产环境使用

FsStateBackend

基于文件系统的状态管理器。

FsStateBackend 构建方法是需要传一个文件路径和是否异步快照。 State 依然在 TaskManager 内存中,但不会像 MemoryStateBackend 是 5 M 的设置上限 Checkpoint 存储在外部文件系统(本地或 HDFS),打破了总大小 Jobmanager 内存的限制。

推荐使用的场景为:常规使用状态的作业、例如分钟级窗口聚合或 join、需要开启HA的作业。

如果使用HDFS,则初始化FsStateBackend时,需要传入以 “hdfs://”开头的路径(即: new FsStateBackend("hdfs:///hacluster/checkpoint")), 如果使用本地文件,则需要传入以“file://”开头的路径(即:new FsStateBackend("file:///Data"))。 在分布式情况下,不推荐使用本地文件。因为如果某个算子在节点A上失败,在节点B上恢复,使用本地文件时,在B上无法读取节点 A上的数据,导致状态恢复失败

RocksDBStateBackend

RocksDB 是一个 key/value 的内存存储系统,和其他的 key/value 一样,先将状态放到内存中,如果内存快满时,则写入到磁盘中,但需要注意 RocksDB 不支持同步的 Checkpoint,构造方法中没有同步快照这个选项。 不过 RocksDB 支持增量的 Checkpoint,意味着并不需要把所有 sst 文件上传到 Checkpoint 目录,仅需要上传新生成的 sst 文件即可。它的 Checkpoint 存储在外部文件系统(本地或HDFS), 其容量限制只要单个 TaskManager 上 State 总量不超过它的内存+磁盘,单 Key最大 2G,总大小不超过配置的文件系统容量即可。

推荐使用的场景为:超大状态的作业,例如天级窗口聚合、需要开启 HA 的作业、最好是对状态读写性能要求不高的作业

自动重启策略

无重启策略

env.setRestartStrategy(RestartStrategies.noRestart());

固定延迟重启策略--开发中使用

env.setRestartStrategy(RestartStrategies.fixedDelayRestart(2, 3000));

失败率重启策略--开发偶尔使用

env.setRestartStrategy(RestartStrategies.failureRateRestart(2, Time.of(4, TimeUnit.SECONDS),  Time.of(1, TimeUnit.SECONDS)));

Savepoint

  • 保存点,类似于以前玩游戏的时候,遇到难关了/遇到boss了,赶紧手动存个档,然后接着玩,如果失败了,赶紧从上次的存档中恢复,然后接着玩
  • 在实际开发中,可能会遇到这样的情况:如要对集群进行停机维护/扩容...那么这时候需要执行一次Savepoint也就是执行一次手动的Checkpoint/也就是手动的发一个barrier栅栏,那么这样的话,程序的所有状态都会被执行快照并保存,当维护/扩容完毕之后,可以从上一次Savepoint的目录中进行恢复!
# 运行job-会自动执行Checkpoint
./bin/flink run --class cn.yxw.checkpoint.CheckpointDemo /root/ckp.jar
# 手动创建savepoint--相当于手动做了一次Checkpoint
./bin/flink savepoint 702b872ef80f08854c946a544f2ee1a5 hdfs://nameservice1/flink-checkpoint/savepoint/
# 停止job
./bin/flink cancel 702b872ef80f08854c946a544f2ee1a5
# 重新启动job,手动加载savepoint数据
./bin/flink run -s hdfs://nameservice1/flink-checkpoint/savepoint/savepoint-702b87-0a11b997fa70 --class cn.yxw.checkpoint.CheckpointDemo /root/ckp.jar 

Savepoint VS Checkpoint

image.png