Flink的容错

一.CheckPoint

1.1CheckPoint介绍

Checkpoint是Flink容错的核心机制,它可以定期的从各个Operator处理的数据进行快照存储,如果Flink程序出现宕机,可以重新从这些快照中恢复数据
每个Checkpoint的应用在启动时,Flink的JobManager为其创建一个CheckpointCoordinator(检查点协调器),CheckpointCoordinator全权负责本应用的快照制作
在这里插入图片描述

  1. CheckpointCoordinator 周期性的向该流应用的所有Source算子发送Barrier
  2. 当某个Source算子收到一个barrier时,便暂停数据处理过程,然后将自己的当前状态制作成快照,并保存到指定的持久化存储中,最后向CheckpointCoordinator报告自己快照制作情况,同时向自身所有下游算子广播该Barrier,恢复数据处理
  3. 下游算子接收到Barrier之后,会暂停自己的数据处理过程,然后将自身的相关状态制作成快照,并保存到指定的持久化存储中,最后向CheckpointCoordinator汇报自身快照的情况,同时向自身所有下游的算子广播该Barrier,恢复数据处理
  4. 每个算子按照第3步骤不断地制作快照,并向下游广播,直到最后Barrier传递到Sink算子,快照制作完成
  5. 当CheckpointCoordinator收到所有的算子的报告后,认为该周期的快照制作成功,否则,如果在规定时间内没有收到所有算子的报告,则认为本周期快照制作失败

单流的Barrier
Flink分布式快照的核心概念之一就是数据栅栏

  • 这些barrier被插入到数据流中,作为数据流的一部分和数据一起向下流动
  • barrier不会干扰正常数据,数据流严格有效,barrier永远不会赶超通常的流记录,它会严格遵循顺序
  • 一个barrier吧数据流分割成两部分,一部分进入当前的快照,另一部分进入下一个快照
  • 每个barrier都有快照ID,并且barrier之前的数据都进入此快照
  • barrier不会干扰数据流处理,所有非常轻量
  • 多个不同快照的多个barrier会在流中间同时出现,即多个快照可能同时创建
    在这里插入图片描述
    两个checkpiont实现流程
    如果一个算子有两个输入源,则战术阻塞先收到该barrier的输入源,等到第二个输入源相同编号的barrier到来时,在制作自身快照并向下游广播该barrier
  1. 假设有算子C有A和B两个输入源,在第i个快照周期中,由于某些原因(入处理延时,网络延时等)输入源A发出来的barrier先到了,这是C算子会暂时将输入源A的输入通道阻塞,仅接收输入源B的数据

在这里插入图片描述

  1. 当输入源B发出的barrier到来时,算子C制作自身快照并向CheckpointCoordinator报告自身的快照情况,然后将两个barrier合并为一个,向下游的所有的算子广播发送

在这里插入图片描述

  1. 由于某些原因出现故障的时候,CheckpointCoordinator通知流图上面的所有算子同一恢复到某个周期的checkpoint状态,然后恢复数据流处理,分布式checkpoint机制保证了数据仅被处理一次(Exactly Once)
    在这里插入图片描述
1.2 CheckPoint持久化

目前Checkpoint持久化存储可以使用如下三种:

  • MemoryStateBackend
  • FsStateBackend
  • RocksDBStateBackend
1.2.1 MemoryStateBackend

MemoryStateBackend是将状态维护在Java堆上的一个内部状态后端,键值状态和窗口算子使用哈希表来存储数据和定时器,当程序chekpoint的时候,此后端会将状态发送给JobManager之前的快照,JobManager也将状态存储在Java堆上,默认情况下,MemoryStateBackend配置支持异步快照,

使用MemoryStateBackend的注意点:

  • 默认情况下,每一个状态的大小限制为5MB,可以通过MemoryStateBackend的构造函数来增加这个大小
  • 状态大小收到akka帧大小的限制,所有无论怎么调整状态大小配置,都不能大于akka的帧大小
  • 状态的总大小不能超过JobManager的内存

何时使用MemoryStateBackend:

  • 本地开发或者调试的时候建议使用MemoryStateBackend,因为这种场景的状态大小是有限的
  • MemoryStateBackend最合适小状态的应用场景
1.2.2 FsStateBackend

该持久化存储主要讲快照数据保存到文件系统中,目前支持的文件系统主要是HDFS和本地文件,如果使用HDFS,则初始化FsStateBackend时,需要传入以"hdfs://"开头的路径,如果使用本地文件,则需要传入

FsStateBackend时候使用的场景:

  • 使用处理大状态,长窗口,或大键值状态的有状态处理任务
  • 非常适合于高可用方案
1.2.3 RocksDBStateBackend

RocksDBStateBackend将处理中的数据使用RocksDB存储在本地磁盘上,在checkpoint时,整个RocksDB数据库会被存储到配置的文件系统中,或者在超大状态作业时可以将增量的数据存在配置的文件中,同时Flink会将极少的元数据存储在JobManager的内存中,或Zookeeper中

1.3 CheckPoint案例演示

需求:

  • 读取服务器hadoop01端口9999的内容,并切分单词,统计数量
  • 要求:开启checkpoint支持,每个5s写入一次HDFS一次
    参考代码
import org.apache.flink.runtime.state.filesystem.FsStateBackend
import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment
import org.apache.flink.api.scala._

object checkpoint {
  def main(args: Array[String]): Unit = {
    //初始化流处理环境
    val env = StreamExecutionEnvironment.getExecutionEnvironment
    //开启checkpoint
    env.enableCheckpointing(5000)
    //指定checkpoint保存的位置
    if (args.length < 1) {
      env.setStateBackend(new FsStateBackend("file:///D:/output/ck"))
    } else {
      env.setStateBackend(new FsStateBackend(args(0)))
    }
    //指定数据源
    val lines = env.socketTextStream("hadoop01", 9999)
    //切分单词,累加数据
    val result = lines.flatMap(_.split(" ")).map(_ -> 1).keyBy(0).sum(1)
    result.print()
    //执行任务
    env.execute()
  }
}

1.4 Externalized CheckPoint

默认情况下,checkpoint不是持久化的,只用于从故障中恢复作业,当程序被取消时,它们会被删除,但是可以配置checkpoint被周期性的持久化到外部,类似于savepoints,这些外部的checkpoint将它们的元数据输出到外部持久化存储并且当作业失败时候不会自动清除,这样如果工作失败了,也有一个checkpoint来恢复

CheckpointConfig config = env.getCheckpointConfig();
config.enableExternalizedCheckpoints(ExternalizedCheckpointCleanup.RETAIN_ON_CANCELLATION);

二.Flink的重启策略

Flink通过重启策略和故障恢复策略来控制Task重启,重启策略决定是否可以重启以及重启的间隔,故障恢复策略决定哪些Task需要重启

2.1 概览

默认的策略是通过Flink的flink-conf.yaml来指定的,这个配置参数restart-strategy定义了那种策略会被采用,如果checkpoint没有启动,就会采用no restart策略,如果启动了checkpoint机制,但是为指定重启策略,会采用fixed-delay策略

重启策略restart-strategy 配置值
固定延时重启策略fixed-delay
故障率重启策略failure-rate
不重启策略none
2.2 固定延时重启策略

按照给定的次数尝试重启作业,如果超过最大的给定次数,作业失败
flink-conf.yaml中设置配置参数,

restart-strategy: fixed-delay

参数说明:

配置参数描述默认配置值
restart-strategy.fixed-delay.attempts作业宣告失败之前 Flink 重试执行的最大次数启用 checkpoint 的话是 Integer.MAX_VALUE,否则是 1
restart-strategy.fixed-delay.delay延时重试意味着执行遭遇故障后,并不立即重新启动,而是延后一段时间。当程序与外部系统有交互时延时重试可能会有所帮助,比如程序里有连接或者挂起的事务的话,在尝试重新执行之前应该等待连接或者挂起的事务超时。启用 checkpoint 的话是 10 秒,否则使用 akka.ask.timeout 的值
2.3 故障率重启策略

故障率重启策略在故障发生之后重启作业,但是当故障率(每个时间间隔发生故障的次数)超过设定的限制时,作业最终会失败,在连续的两次重启尝试下,重启策略等待一段固定长度的时间

flink-conf.yaml中设置参数

restart-strategy: failure-rate
配置参数描述配置默认值
restart-strategy.failure-rate.max-failures-per-interval单个时间间隔内允许的最大重启次数1
restart-strategy.failure-rate.failure-rate-interval测量故障率的时间间隔1 分钟
restart-strategy.failure-rate.delay连续两次重启尝试之间的延时akka.ask.timeout
2.4 不重启策略

作业直接失败,不尝试重启

restart-strategy: none
2.5 案例

基于单词统计进行改造,当遇到"error"字符串的时候,程序抛出异常,出现3次异常后,程序退出

参考代码

package streaming

import org.apache.flink.api.common.restartstrategy.RestartStrategies
import org.apache.flink.runtime.state.filesystem.FsStateBackend
import org.apache.flink.streaming.api.environment.CheckpointConfig.ExternalizedCheckpointCleanup
import org.apache.flink.streaming.api.scala._

object FixDelayRestartStrategyDemo {
  def main(args: Array[String]): Unit = {
    //初始化流处理执行环境
    val env = StreamExecutionEnvironment.getExecutionEnvironment
    //设置checkpoint检查点
    env.enableCheckpointing(5000)
    env.setStateBackend(new FsStateBackend("hdfs://hadoop01:8020/flink-checkpoint/checkpoint"))
    env.getCheckpointConfig.enableExternalizedCheckpoints(ExternalizedCheckpointCleanup.RETAIN_ON_CANCELLATION)
    env.getCheckpointConfig.setMaxConcurrentCheckpoints(1)
    //设置重启策略,默认的重启策略是不停的重启
    //固定延迟重启策略:程序出现异常的时候,重启三次,每次5s重启,超过三次程序退出
    env.setRestartStrategy(RestartStrategies.fixedDelayRestart(3, 5000))
    val lines = env.socketTextStream("hadoop01", 9999)
    val result = lines.flatMap(_.split(",")).map(word => {
      if (word.equals("error")) {
        throw new RuntimeException("出现错误,程序重启!")
      }
      (word, 1)
    }).keyBy(0).sum(1)
    result.print()
    env.execute()
  }
}

三.Savepoint

Save是依据Flink checkpointing机制所创建的流作业执行状态的一致镜像,你可以使用Savepoint进行Flink作业的启动和重启,fork或者更新
Savepoint分为两部分:温蒂存储上包含的二进制文件的目录(通常恒大),和元数据(相对较小),稳定存储上的文件表示作业执行状态的数据镜像,Savepoint的元数据文件以(绝对路径)的形式包含(主要)指向作为Savepoint的一部分稳定存储上的所有文件的指针

Savepoint和Checkpoint的不同之处类似于传统数据库中的备份和恢复日志之间的差异

  • checkpoint的主要目的是为意外失败的作用提供恢复机制
  • Checkpoint的生命周期由Flink管理,即Flink创建,管理和删除CheckPoint-无需用户交互
  • 作为一种恢复和定期触发的方法,checkpoint实现由两个设计目标,1) 轻量级创建 2) 尽可能快的恢复
  • Savepoint由用户创建,拥有和删除
Savepoint演示
# 启动yarn session
cd /export/servers/flink-1.7.2
bin/yarn-session.sh -n 2 -tm 800 -s 1 -d

# 运行job
bin/flink run --class com.itheima.checkpoint.FixDelayRestartStrategyDemo flink-base-1.0-SNAPSHOT.jar

# 创建savepoint
bin/flink savepoint e3391db4d9655b85ddfda1e9c37788ed hdfs://node01:8020/flink-checkpoint/savepoint/

# 停止job
bin/flink cancel e3391db4d9655b85ddfda1e9c37788ed

# 重新启动job,加载savepoint数据
bin/flink run -s file:/flink-checkpoint/savepoint/savepoint-a837f5-64896400708e --class com.itheima.checkpoint.FixDelayRestartStrategyDemo flink-base-1.0-SNAPSHOT.jar

# 停止yarn session
yarn application -kill application_1572703223538_0003
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值