Checkpoints概述

  • Flink 故障恢复机制的核心, 就是应用状态的一致性检查点
  • 有状态流应用的一 致检查点,其实就是所有任务的状态,在某个时间点的一份拷贝(一份快照) ;这个时间点,应该是所有任务都恰好处理完一个相同的输入数据的时候

原理演示图

Checkpoints

  • 当前数据接收到5,Checkpoints会保存5处理完以后的快照

    出现故障

flink的checkpoint和spark的checkpoint flink中checkpoint_数据


开始恢复

  • 遇到故障之后,第一步就是重启应用
  • flink的checkpoint和spark的checkpoint flink中checkpoint_flink_02

  • 第二步是从checkpoint中读取状态,将状态重置
  • 从检查点重新启动应用程序后,其内部状态与检查点完成时的状态完全相同

flink的checkpoint和spark的checkpoint flink中checkpoint_检查点_03

  • 第三步:开始消费并处理检查点到发生故障之间的所有数据

flink的checkpoint和spark的checkpoint flink中checkpoint_数据_04

  • 这种检查点的保存和恢复机制可以为应用程序状态提供“精确一次” (exactly-once)的一致性,因为所有算子都会保存检查点并恢复其所有状态,这样一来所有的输入流就都会被重置到检查点完成时的位置

Checkpoints改进实现

  • 基于Chandy-Lamport算法的分布式快照
  • 将检查点的保存和数据处理分离开,不暂停整个应用

检查点分界线(Checkpoint Barrier)

  • Flink的检查点算法用到了一种称为分界线(barrier) 的特殊数据形式,用来把一条流上数据按照不同的检查点分开
  • 分界线之前到来的数据导致的状态更改,都会被包含在当前分界线所属的检查点中;而基于分界线之后的数据导致的所有更改,就会被包含在之后的检查点中

其实就是当JobManager向source发送Cheeckpoints ID时,source就会在当前位置插入barrier点,当source执行到barrier点时,就会停下工作,执行快照操作,但后面的任务并没有停止的,而是继续执行没有执行完的数据,当source执行完快照任务时,就会向后面的任务广播barrier点,后面的任务当处理到barrier点时同样会执行快照操作,依旧不影响其他任务执行,然后依次往下传递barrier点,直到所有任务都执行了快照操作,最后会将这次的所有快照进行合并,就得到了一次完整得快照

原理演示图(barrier)

  • 现在是一个有两个输入流的应用程序,用并行的两个Source任务来读取
  • JobManager 会向每个source任务发送一条带有新检查点ID 的消息,通过这种方式来启动检查点
  • 数据源将它们的状态写入检查点,并发出一个检查点barrier
  • 状态后端在状态存入检查点之后,会返回通知给source任务, source 任务就会向JobManager确认检查点完成

flink的checkpoint和spark的checkpoint flink中checkpoint_flink_05

  • 分界线对齐: barrier 向下游传递,sum任务会等待所有输入分区的barrier到达
  • 对于barrier已经到达的分区,继续到达的数据会被缓存
  • 而barrier尚未到达的分区,数据会被正常处理

flink的checkpoint和spark的checkpoint flink中checkpoint_检查点_06

  • 当收到所有输入分区的barrier 时,任务就将其状态保存到状态后端的检查点中,然后将barrier继续向下游转发

flink的checkpoint和spark的checkpoint flink中checkpoint_重启_07

  • 向下游转发检查点barrier后,任务继续正常的数据处理
  • Sink任务向JobManager确认状态保存到checkpoint完毕
  • 当所有任务都确认已成功将状态保存到检查点时,检查点就真正完成了

Checkpoints配置参数

  • 配置Checkponts间隔时间
//配置间隔1秒
	env.enableCheckpointing(1000L)
  • 配置严格程度
//AT_LEAST_ONCE:最少一次
    //EXACTLY_ONCE:只有一次
    env.getCheckpointConfig.setCheckpointingMode(CheckpointingMode.EXACTLY_ONCE)
  • 设置超时时间,超时的部分丢弃
//配置超时时间60秒
   env.getCheckpointConfig.setCheckpointTimeout(60000L)
  • 最大并行的Checkponts(默认不配的情况下是一个)
//配置最大并行的Checkpoint数量为2
    env.getCheckpointConfig.setMaxConcurrentCheckpoints(2)
  • Checkpoint之间至少间隔的时间(如果配置这一条,配置的最大并行数就会失效)
//配置至少间隔500毫秒
    env.getCheckpointConfig.setMinPauseBetweenCheckpoints(500L)
  • 配置是否更倾向于使用Checkpoint恢复故障,默认false
//配置优先使用Checkpoint恢复故障
	env.getCheckpointConfig.setPreferCheckpointForRecovery(true)
  • 配置Checkpoint失败最大容忍次数(默认0次,如果Checkpoint失败也重启)
//配置最大容忍失败次数为3
    env.getCheckpointConfig.setTolerableCheckpointFailureNumber(3)

配置示例

val env: StreamExecutionEnvironment = StreamExecutionEnvironment.getExecutionEnvironment
    //配置Checkponts间隔时间
    env.enableCheckpointing(1000L)
    //配置严格程度
    //AT_LEAST_ONCE:最少一次
    //EXACTLY_ONCE:只有一次
    env.getCheckpointConfig.setCheckpointingMode(CheckpointingMode.EXACTLY_ONCE)
    //设置超时时间,超时的部分丢弃
    env.getCheckpointConfig.setCheckpointTimeout(60000L)
    //最大并行的Checkponts(默认不配的情况下是一个)
    env.getCheckpointConfig.setMaxConcurrentCheckpoints(2)
    //两次Checkpoint之间至少间隔的时间
    env.getCheckpointConfig.setMinPauseBetweenCheckpoints(500L)
    //配置是否更倾向于使用Chechpoint恢复故障,默认false
    env.getCheckpointConfig.setPreferCheckpointForRecovery(true)
    //配置Checkpoint失败最大容忍次数(默认0次,如果Checkpoint失败也重启)
    env.getCheckpointConfig.setTolerableCheckpointFailureNumber(3)
  }