Flink 容错详解

一、背景

Flink的容错机制,就是checkpoint;把状态保存起来,用于容错;否则,状态就失去了存在的意义。

二、checkpoint详解

1)概念

①一种连续周期性绘制数据流状态的机制。这种机制确保即使程序出现故障,也可以顺利恢复到故障之前的状态,确保exactly once语义的保证。

   注意:这种保证,只能在flink内部系统做保证,对于外部的source和sink,需要外部主键一同保证

②全局快照,持久化保存所有的task和operator的state

③可以通过配置,使用at least once语义保证

④checkpoint是通过分布式snapshot实现的

2)特点

①可异步:在程序正常运行的过程中,异步完成,不会干扰程序的正常运行

②全量/增量:一般是全量;也可设置增量

③barrier机制

④失败后回滚最近一次成功的checkpoint

3)前提条件

①在一定时间内可回溯的DataSource(故障是可以恢复),常见的有:

  1. 可持久化的队列:Kafka,RabbitMQ等
  2. 文件系统:HDFS,S3,GFS,NFS,Ceph

②可持久化存储state的存储系统,通常使用分布式文件系统

  1. 一般使用HDFS,S3,GFS,NFS,Ceph等

三、过程

1)checkpoint

将各个state保存起来到指定的存储系统中(checkpoint)

2)restore

恢复所有状态

四、使用

1)第一步:启用checkpoint

    StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();

    // checkpoint默认是禁用的;启用checkpoint
    // 每1000毫秒做一次checkpoint
    env.enableCheckpointing(1000);

    // 设置checkpoint的模式为 exactly-once(默认配置)
    env.getCheckpointConfig().setCheckpointingMode(CheckpointingMode.EXACTLY_ONCE);

    // 设置每两个checkpoint之间最小时间间隔
    env.getCheckpointConfig().setMinPauseBetweenCheckpoints(500);

    // 设置checkpoint超时时间
    env.getCheckpointConfig().setCheckpointTimeout(60000);

    // 设置同一时间checkpoint的最大并行数
    env.getCheckpointConfig().setMaxConcurrentCheckpoints(1);

    // 任务流取消和故障时会保留Checkpoint数据,以便根据实际需要恢复到指定的Checkpoint
    env.getCheckpointConfig().enableExternalizedCheckpoints(CheckpointConfig.ExternalizedCheckpointCleanup.RETAIN_ON_CANCELLATION);

①checkpoint的模式 CheckpointMode

  1. CheckpointMode.EXACTLY_ONCE
  2. CheckpointMode.AT_LEAST_ONCE
  3. 一般选择EXACTLY_ONCE,除非场景要求极低的延迟(几毫秒)
  4. 如果需要保证整个流程的EXACTLY_ONCE,source和sink也需要保证EXACTLY_ONCE 

②checkpoint的保留策略 ExternalizedCheckpointCleanup

  1. 默认情况下,检测点不被保留,仅用于从故障中恢复作业,可以启用外部持久化检查点,同时制定保留策略
  2. ExternalizedCheckpointCleanup.RETAIN_ON_CANCELLATION,在作业被取消时保留检查点;这种情况下,必须在作业取消之后,手动清理检查点状态。
  3. ExternalizedCheckpointCleanup.DELETE_ON_CANCELLATION,在作业被取消时清理检查点;这种情况下,检查点状态只有在作业失败重启时可用,手动取消作业,检查点被清理不可用。

③checkpoint的超时时间

  1. env.getCheckpointConfig().setCheckpointTimeout(6000)
  2. 超过时间没有完成,则会被终止

④checkpoint的最小间隔

  1. env.getCheckpointConfig().setMinPauseBetweenCheckpoints(500)
  2. 用于指定上一个checkpoint完成之后至少等多久才可以发出另一个checkpoint
  3. 当指定这个参数时,maxConcurrentCheckpoints的值为1
    备注:个人觉得,设置周期并设置最小间隔 最合理

⑤checkpoint的最多并行度

  1. env.getCheckpointConfig().setMaxConcurrentCheckpoints(1)
  2. 用于指定同时运行的checkpoint可以有多少个

⑥checkpoint的异常处理

  1. env.getCheckpointConfig().setFailOnCheckpointingErrors(true)
  2. 用于指定在checkpointing发生异常时,是否应该使该task失败重试
  3. 默认为true
  4. 如果设置为false,在checkpoint失败后,任务仍然会继续运行

2)第二步:选择合适的state Backend

①快照保存位置

  1. State Backend决定:MemoryStateBackend(默认)、FsStateBackend、RocksDBStateBackend
  2. 默认state保存在taskmanager的内存中,checkpoint存储在JobManager的内存中(MemoryStateBackend)

②保存的内容

Checkpoint机制会持久化所有状态的一次性快照,这些状态包括:

非用户定义的状态:timers、非用户定义的stateful operators(connectors,windows)

用户定义的状态:用户自定义的stateful operator所使用的Keyed State 和 Operator State

3)第三步:配置重启策略

①重启策略说明

Flink支持不同的重启策略,这些策略控制 在出现故障时如何重新启动job
 

Restart Strategy配置项默认值说明
固定延迟(Fixed delay)restart-strategy: fixed-delay 如果超过最大尝试次数,作业最终会失败,在连续两次重启尝试之间等待固定时间
restart-strategy: fixed-delay.attempts: 31(启动Checkpoint和延迟策略使用fixed-delay,但是没配置fixed-delay.attempts)或者
Integer.MAX_VALUE(启用checkpoint但未指定重启策略时)

restart-strategy: fixed-delay.delay: 10s

akka.ask.timeout (启动checkpoint和延迟策略使用fixed-delay,但是没配置fixed-delay.delay)或者
10s(启动checkpoint,但是没指定重启策略)
失败率(Failure rate)restart-strategy: failure-rate 在失败后重新启动作业,但是当超过故障率(每个时间间隔的故障)时,作业最终会失败,在连续两次重启尝试之间等待固定的时间
restart-strategy: failure-rate.max-failures-per-interval: 31
restart-stragery: failure-rate.failure-rate-interval: 5 min1 minute

restart-stragery: failure-rate.delay: 10s

akka.ask.timeout
无启动(No restart)restart-strategy: none 如果没有启动checkpointing,则使用无重启(no restart)策略

注意:代码配置会覆盖配置文件配置,即代码配置优先于配置文件配置。

②tips

  1. 如果没有启用checkpointing,则使用无重启(no restart)策略
  2. 如果启用了checkpointing,但没有配置重启策略,则使用固定延迟(fixed-delay)策略,其中尝试重启次数是Integer.MAX_VALUE
  3. 重启策略可以在flink-conf.yaml中配置,表示全局的配置。也可以在应用代码中动态指定,会覆盖全局配置

4)三个保存策略详解

①MemoryStateBackend

  1. MemoryStateBackend在Java堆上维护状态,Key/value状态和窗口运算符使用哈希表存储值和计时器等
  2. Checkpoint时,MemoryStateBackend对State做一次快照,并在向JobManager发送checkpoint确认完成的消息中带上此快照数据,然后快照就会存储在JobManager的堆内存中
  3. MemoryStateBackend可以使用异步方式进行快照(默认开启),推荐使用异步的方式,避免阻塞。如果极特殊情况不希望异步,可以在构造的时候传入false(也可以通过全局配置文件指定),如下
  4. 限制:
    单个state的大小限制为5MB,可以在MemoryStateBackend的构造函数中增加
    不论如何配置,state的大小都无法大于 akka.framesize(JobManager 和 TaskManager之间发送的最大消息的大小默认是10MB)
    JobManager必须有足够的内存大小
  5. 使用场景:
    本地开发和测试
    小状态job,如只使用Map、FlatMap、Filter... 或 Kafka Consumer

②FsStateBackend

  1. 需要配置一个文件系统的URL,比如"hdfs://namenode:40010/flink/checkpoint"或者"file:///data/flink/checkpoints"
  2. FsStateBackend在TaskManager的内存中持有正在处理的数据。Checkpoint时将state snapshot写入文件系统目录下的文件中。文件的路径等元数据会传递给JobManager,存在其内存中(或者在HA模式下,存储在元数据checkpoint中)
  3. FsStateBackend可以使用异步的方式进行快照(默认开启),推荐使用异步的方式避免阻塞。如果极特殊情况下不希望异步,可以在构造的时候传入false(也可以通过全局配置文件制定),如下
  4. 使用场景:
    大状态,长窗口,大键/值状态的job
    所有高可用性的情况

③RocksDBStateBackend

  1. Flink内部维护,不需要用户维护,对于用户透明
  2. RocksDBStateBackend需要配置一个文件系统的URL,如"hdfs://namenode:40010/flink/checkpoint"或者"file:///data/flink/checkpoints"。
  3. RocksDBStateBackend将运行中的数据保存在RocksDB数据库中,(默认情况下)存储在TaskManager数据目录中。在Checkpoint时,整个RocksDB数据库将被checkpointed到配置的文件系统中和目录中。文件的路径等元数据会传输给JobManager,存在其内存中(或者在HA模式下,存储在元数据checkpoint中)。
  4. RocksDBStateBackend总是执行异步快照
  5. 限制:
    RocksDB JNI API是基于 byte[],因此 key 和 value 最大支持大小为2^31个字节(2GB)。RocksDB自身在支持较大value时候有问题(merge operations in RocksDB(e.g. ListState))
  6. 适用场景
    超大状态、超长窗口、大键/值状态的job
    所有高可用性的情况
  7. 与前两种状态后端对比
    目前只有RocksDBStateBackend支持增量checkpoint(默认全量)
    状态保存在数据库中,即使用RocksDB可以保存的状态量仅受可用磁盘空间量的限制,相比其他状态后端可保存更大的状态,但开销更大(读/写需要反序列化 / 序列化去检索 / 存储状态),吞吐受到限制

④StateBackend总结 

State Backendin-flightcheckpoint异步增量checkpoint吞吐适用场景
MemoryStateBackend(默认)TM MemoryJM Memory默认异步不支持调试、无状态、小状态或对数据丢失或者重复无要求的job
FsStateBackendTM MemoryFS / HDFS默认异步不支持大状态、长窗口、大键 / 值状态的job
RocksDBStateBackendRocksDB on TMFS / HDFS总是异步支持越大状态、超长窗口、大型KV结构

⑤StateBackend配置

  1. 全局配置(配置文件conf/flink-conf.yaml)
    # The backend that will be used to store operator state checkpoints
    
    state.backend: filesystem
    
    # Direcroty for storing checkpoints
    
    state.checkpoints.dir: hdfs://namenode:40010/flink/checkpoints

     

  2. 每个job单独配置State Backend(可覆盖全局配置)
  3. Checkpointing的相关配置(conf/flink-conf.yaml)
     
    配置项默认值说明
    (*)state.backend(none)
    1. 用于指定checkpoint state存储的backend,默认为none
    2. 目前支持的backends是‘jobmanager’,‘filesystem’,‘rocksdb’
    3. 也可以使用它们的工厂类的全限定名:例如org.apache.flink.runtime.state.filesystem.FsStateBackendFactory
    4. 如果没有指定,默认使用jobmanager,即MemoryStateBackend
    (*)state.backend.asynctrue用于指定backend是否使用异步,有些不支持async或者只支持async的state backend可能会忽略这个参数
    state.backend.fs.memory-threshold1024用于指定存储state的files大小阈值,如果小于该值,则会存储在root checkpoint metadata file
    state.backend.incrementalfalse用于指定是否采用增量checkpoint,有些不支持增量checkpoint的backend会忽略该配置;目前只有rockddb支持
    state,backend.local-recoveryfalse 
    (*)state.checkpoints.dir(none)
    1. 用于指定checkpoint的data files 和 meta data存储的目录,该目录必须对所有参与的TaskManager 和 JobManager 可见(有读写权限)
    2. 例如:hdfs://namenode-host:port/flink-checkpoints
    (*)state.checkpoints.num-retained1

    用于指定保留的已完成的checkpoints最大个数

    (*)state.savepoints.dir(none)
    1. 用于指定savepoints的默认目录
    2. 例如:hdfs://namenode-host:port/flink-checkpoints
    taskmanager.state.local.root-dirs(none) 

⑥使用RocksDBStateBackend

  1. 特有配置(conf/flink-conf/yaml)
     
    配置项默认值说明
    state.backend.rocksdb.localdir(none) 
    state.backend.rocksdb.timerservice.factory"HEAP"

    指定timer service状态存储在哪里,HEAP / ROCKSDB

  2. 代码配置


    备注:以上配置,需要在pom中添加如下依赖

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值