Flink基础学习笔记(四)Checkpoint与重启策略

写在前面

本章主要介绍了Flink的Checkpoint的基本概念和原理,以Checkpoint为基础说明Flink的重启策略,并最后和Savepoint进行对比。其实,Checkpoint本质上就是一种算法,用于实现State的保存,因为存在State和Checkpoint的存在,所以程序重启后可以进行状态的恢复并继续运行。

1、Checkpoint

1.1、Checkpoint概述

Checkpoint机制是Flink可靠性的基石,可以保证Flink集群在某个算子因为某些原因(如异常退出)出现故障时,能够将整个应用流图的状态恢复到故障之前的某一状态,保证应用流图状态的一致性。
检查点的两种实现:
(1)检查点算法的简单实现–暂停应用,保存状态到检查点,在重新恢复应用
(2)Flink基于检查点算法的优化实现–基于Chandy-Lamport算法的分布式快照,将检查点的保存和数据分开处理,不需要暂停整个应用,这里引入State Backend的概念。

下图sum_even (2+4),sum_odd(1 + 3 + 5),5这个数据之前的都处理完了,就出保存一个checkpoint;Source任务保存状态5,sum_event任务保存状态6,sum_odd保存状态是9;这三个保存到状态后端中就构成了CheckPoint;Flink故障恢复机制的核心,就是应用状态的一致性检查点;
有状态流应用的一致性检查点(checkpoint),其实就是所有任务的状态,在某个时间点的一份拷贝(一份快照);这个时间点,应该是所有任务都恰好处理完一个相同的输入数据的时候 。(这个同一时间点并不是物理上的在同一时刻)
在这里插入图片描述

1.2、Checkpoint算法实现

Flink基于Chandy-Lamport算法实现了分布式快照的检查点。该算法不会暂停整个应用程序,而是将检查点与处理分离,使得一些任务在继续处理的同时,其他任务可以持久化它们的状态。
注:本质上就是照相全体处理和照相分批处理的例子。

它使用一种特殊类型的记录,称为Checkpoint barrier。类似于watermarks,barrier由Source注入到常规记录流中,并且不能被其他记录追越或越过。检查点屏障携带Checkpoint ID以标识其所属的检查点,并在逻辑上将流分成两部分。由于位于barrier之前的记录引起的所有状态修改都包含在屏障的检查点中,而由于位于barrier之后的记录引起的所有修改都包含在稍后的检查点中。

1、这里有一个简单的流式应用程序示例,以逐步解释该算法。该应用程序包括两个Source Task,每个任务消耗一个递增数字的流。Source的输出被分为偶数和奇数数字的流。每个分区由一个任务处理,该任务计算接收到的所有数字的总和,并将更新后的总和转发到一个sum Task。
在这里插入图片描述
2、JobManager会向每个source任务发送一个带有检查点id的消息,启动检查点(如图中ID=2)通过这种方式启动检查点,sum odd(1+1+3),sum even(2)

在这里插入图片描述3、 Source将它们的状态写入检查点,并发出一个Checkpoint Barrier;状态后端在状态存入检查点之后,会返回通知给source任务,source任务就会向JobManager确认检查点完成。source1和source2收到检查点ID = 2时,分别存入自己的偏移量蓝3和黄4,存完之后返回一个ID2通知JobManager快照已保存好;(此处为异步操作,在保存快照时它会暂停发送和处理数据,同时它也会向下游发送带有检查点ID的barrier,发送的方式直接广播;这个过程中Sum和sink任务也没闲着都在处理数据)
在这里插入图片描述
4、 分界线对齐(barrier对齐):barrier向下游传递,sum任务会等待所有输入分区的的barrier到达;对于barrier已经到达的分区,继续到达的数据会被缓存;而barrier尚未到达的分区,数据会被正常处理;(比如蓝2通知给了Sum even,它会等黄2的barrier到达,这时处理的数据4来了,会先被缓存因为它数据下一个checkpoint的数据; 黄2的checkpoint还没来这时它如果来数据还会正常处理更改状态,如下图的在黄2的barrier还没来之前,source2的数据来了条4,它会正常处理Sum event(2 + 2 + 4))
在这里插入图片描述
5、 当收到所有输入分区的barrier时,任务就将其状态保存到状态后端的检查点中,然后将barrier继续向下游转发。barrier对齐之后(Sum even和Sum odd都接收到了两个source发来的barrier),将它们各自的8状态存入checkpoint中;接下来继续向下游Sink广播barrier;
在这里插入图片描述
6、向下游转发检查点的barrier后,任务继续正常的数据处理;先处理缓存的数据,蓝4加载进来Sum event 12,黄6进来Sum event 18。
在这里插入图片描述
7、 Sink任务向JobManager确认状态保存到checkpoint完毕;(Sink接收到barrier后先保存状态到checkpoint,然后向JobManager汇报)当所有任务都确认已成功将状态保存到检查点时,检查点就真正完成了。
在这里插入图片描述

1.3、从Checkpoint恢复

1、程序失败
此时, sum_even(2 + 4 + 6);sum_odd(1 + 3 + 5);
在这里插入图片描述
2、重启应用
在执行应用程序期间,Flink会定期保存状态的一致性检查点;发生故障,Flink将会使用最近的检查点来一致恢复应用程序的状态,并重新启动处理流程;
在这里插入图片描述
3、从检查点恢复数据
从checkpoint中读取状态,将状态重置;从检查点重新启动应用程序后,其内部状态与检查点完成时的状态完全相同;
在这里插入图片描述
4、继续运行
开始消费并处理检查点到发生故障之间的所有数据;
这种检查点的保存和恢复机制可以为应用程序状态提供“精确一次”(exactly-once)的一致性,因为所有算子都会保存检查点并恢复其所有状态,这样一来所有的输入流就都会被重置到检查点完成时的位置。
在这里插入图片描述

1.4、Checkpoint代码中设置

1.4.1、Checkpoint配置

默认Checkpoint功能是disabled的,想要使用的时候需要先启用,checkpoint开启之后,CheckPointMode有两种,Exactly-onceAt-least-once,默认的checkPointMode是Exactly-once,Exactly-once对于大多数应用来说是最合适的。At-least-once可能用在某些延迟超低的应用程序(始终延迟为几毫秒)。

默认checkpoint功能是disabled的,想要使用的时候需要先启用
StreamExecutionEnvironment env =
StreamExecutionEnvironment.getExecutionEnvironment();
// 每隔1000 ms进行启动一个检查点【设置checkpoint的周期】
env.enableCheckpointing(1000);
// 高级选项:
// 设置模式为exactly-once (这是默认值)
env.getCheckpointConfig().setCheckpointingMode(CheckpointingMode.EXACTLY_ONCE);
// 确保检查点之间有至少500 ms的间隔【checkpoint最小间隔】
env.getCheckpointConfig().setMinPauseBetweenCheckpoints(500);
// 检查点必须在一分钟内完成,或者被丢弃【checkpoint的超时时间】
env.getCheckpointConfig().setCheckpointTimeout(60000);
// 同一时间只允许进行一个检查点
env.getCheckpointConfig().setMaxConcurrentCheckpoints(1);
// 表示一旦Flink处理程序被cancel后,会保留Checkpoint数据,以便根据实际需要恢复到指定的
Checkpoint【详细解释见备注】
env.getCheckpointConfig().enableExternalizedCheckpoints(ExternalizedCheckpointCl
eanup.RETAIN_ON_CANCELLATION);

默认情况下,如果设置了Checkpoint选项,则Flink只保留最近成功生成的1个Checkpoint,而当Flink 程序失败时,可以从最近的这个Checkpoint来进行恢复。但是,如果我们希望保留多个Checkpoint, 并能够根据实际需要选择其中一个进行恢复,这样会更加灵活,比如,我们发现最近4个小时数据记录处理有问题,希望将整个状态还原到4小时之前Flink可以支持保留多个Checkpoint,需要在Flink的配置文件conf/flink-conf.yaml中,添加如下配置,指定最多需要保存Checkpoint的个数:
state.checkpoints.num-retained: 20

这样设置以后就查看对应的Checkpoint在HDFS上存储的文件目录
hdfs dfs -ls hdfs://namenode:9000/flink/checkpoints
如果希望回退到某个Checkpoint点,只需要指定对应的某个Checkpoint路径即可实现

1.4.2、从Checkpoint恢复数据

如果Flink程序异常失败,或者最近一段时间内数据处理错误,我们可以将程序从某一个Checkpoint点
进行恢复

bin/flink run -s
hdfs://namenode:9000/flink/checkpoints/467e17d2cc343e6c56255d222bae3421/chk-56/_metadata flink-job.jar

程序正常运行后,还会按照Checkpoint配置进行运行,继续生成Checkpoint数据。
当然恢复数据的方式还可以在自己的代码里面指定checkpoint目录,这样下一次启动的时候即使代码发生了改变就自动恢复数据了。

2、Savepoint

2.1、Savepoint概述

Flink还提供了可以自定义的镜像保存功能,就是保存点(savepoints);原则上,创建保存点使用的算法与检查点完全相同,因此保存点可以认为就是具有一些额外元数据的检查点;Flink不会自动创建保存点,因此用户(或者外部调度程序)必须明确地触发创建操作;保存点是一个强大的功能,除了故障恢复外,保存点可以用于:有计划的手动备份,更新应用程序,版本迁移,暂停或重启应用,等等.

Flink通过Savepoint功能可以做到程序升级后,继续从升级前的那个点开始执行计算,保证数据不中断全局,一致性快照。可以保存数据源offset,operator操作状态等信息,可以从应用在过去任意做了
Savepoint的时刻开始继续消费。

  • Checkpoint
    应用定时触发,用于保存状态,会过期,内部应用失败重启的时候使用。
  • Savepoint
    用户手动执行,是指向Checkpoint的指针,不会过期,在升级的情况下使用。
    注意:为了能够在作业的不同版本之间以及 Flink 的不同版本之间顺利升级,强烈推荐程序员通过uid(String) 方法手动的给算子赋予 ID,这些 ID 将用于确定每一个算子的状态范围。如果不手动给各算子指定 ID,则会由 Flink 自动给每个算子生成一个 ID。只要这些 ID 没有改变就能从保存点(savepoint)将程序恢复回来。而这些自动生成的 ID 依赖于程序的结构,并且对代码的更改是很敏感的。因此,强烈建议用户手动的设置 ID。

2.2、Savepoint的使用

  1. 在flink-conf.yaml中配置Savepoint存储位置
    不是必须设置,但是设置后,后面创建指定Job的Savepoint时,可以不用在手动执行命令时指定
    Savepoint的位置
    state.savepoints.dir: hdfs://namenode:9000/flink/savepoints
  2. 触发一个savepoint【直接触发或者在cancel的时候触发】
    停止程序:bin/flink cancel -s [targetDirectory] jobId [-yid yarnAppId]【针对on yarn模式需要指定-yid参数】
  3. 从指定的savepoint启动job
    bin/flink run -s savepointPath [runArgs]

3、重启策略

3.1、重启策略概述

Flink支持不同的重启策略,以在故障发生时控制作业如何重启,集群在启动时会伴随一个默认的重启策略,在没有定义具体重启策略时会使用该默认策略。 如果在工作提交时指定了一个重启策略,该策略会覆盖集群的默认策略,默认的重启策略可以通过 Flink 的配置文件 flink-conf.yaml 指定。配置参数restart-strategy 定义了哪个策略被使用。
常用的重启策略
(1)固定间隔 (Fixed delay)
(2)失败率 (Failure rate)
(3)无重启 (No restart)
如果没有启用 checkpointing,则使用无重启 (no restart) 策略。如果启用了 checkpointing,但没有配置重启策略,则使用固定间隔 (fixed-delay) 策略, 尝试重启次数默认值是:Integer.MAX_VALUE,重启策略可以在flink-conf.yaml中配置,表示全局的配置。也可以在应用代码中动态指定,会覆盖全局配置。

3.2、重启策略的配置

  • 固定间隔 (Fixed delay)
第一种:全局配置 flink-conf.yaml
restart-strategy: fixed-delay
restart-strategy.fixed-delay.attempts: 3
restart-strategy.fixed-delay.delay: 10 s
第二种:应用代码设置
env.setRestartStrategy(RestartStrategies.fixedDelayRestart(
3, // 尝试重启的次数
Time.of(10, TimeUnit.SECONDS) // 间隔
));
  • 失败率 (Failure rate)
第一种:全局配置 flink-conf.yaml
restart-strategy: failure-rate
restart-strategy.failure-rate.max-failures-per-interval: 3
restart-strategy.failure-rate.failure-rate-interval: 5 min
restart-strategy.failure-rate.delay: 10 s
第二种:应用代码设置
env.setRestartStrategy(RestartStrategies.failureRateRestart(
3, // 一个时间段内的最大失败次数
Time.of(5, TimeUnit.MINUTES), // 衡量失败次数的是时间段
Time.of(10, TimeUnit.SECONDS) // 间隔
));
  • 无重启 (No restart)
第一种:全局配置 flink-conf.yaml
restart-strategy: none
第二种:应用代码设置
env.setRestartStrategy(RestartStrategies.noRestart());

参考链接

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值