Flink 容错机制
作用:保证故障后的恢复。最重要的是检查点。
Checkpoint
将之前某个时间点所有状态保存下来。
=> 故障重启的时候,可以从检查点读档,恢复之前的状态。
检查点的保存
- 周期性触发保存(设置间隔时间)
- 在所有任务(算子)都恰好处理完一个相同的输入数据时候,将状态保存下来。
- 此时,如果出现故障,只需要让source任务向数据源重新提交偏移量、请求重放数据即可。
- 具体流程
- 关键是要等所有任务将同一个数据处理完毕。
检查点算法
如何不暂停整体流处理前提下,将状态备份保存到检查点?—— Chandy-Lamport 算法
- 检查点分界线 Barrier
- 表示触发检查点保存的时间点。遇到该标识则证明之前的数据都处理完了,可以保存一个检查点。
- 把一条流上数据按照不同检查点分开,即表示检查点的分界线。
- 分布式快照算法——异步分界线快照
- 当上游任务向多个并行下游任务发送barrier时,需要广播出去
- 多个上游任务向同一个下游任务传递分界线时,需要在下游执行分界线对其,等所有并行分区barrier到期才开始状态的保存。
检查点配置
env.enableCheckpointing(1000); // 启用检查点
env.getCheckpointConifg().setCheckpointStorage(new JobManagerCheckpointStorage());
// 配置存储检查点到 JobManager 堆内存
env.getCheckpointConfig().setCheckpointStorage(new FileSystemCheckpointStorage("hdfs://.."))
// 配置存储检查点到文件系统
其他配置
- 检查点模式 CheckpointingMode
- “精确一次”:exactly-once;“至少一次”:at-least-once
- 超时时间 checkpointTimeout
- 最小时间间隔 minPauseBetweenCheckpoints
- 最大并发检查点数量 maxConcurrentCheckpoints
- 开启外部持久化存储 enableEXternalizedCheckpoints
- 检查点连续失败次数 tolerableCheckpointFailureNumber
- 非对齐点检查 enableUnalignedCheckpoints
- 不再执行检查点分界线对其操作
- 对齐检查点超时时间
- 超过设定时间后自动切换为非对齐检查
实现过程
public class CheckpointConfigDemo {
public static void main(String[] args) {
StreamExecutionEnvironment environment = StreamExecutionEnvironment.
getExecutionEnvironment();
environment.setParallelism(1);
// 使用hdfs保存检查点,导入依赖
System.setProperty("HADOOP_USER_NAME","root");
/*
* TODO 配置检查点
* 1.启动检查点
* 2.指定检查点的存储位置
* 3.设置 checkpoint 超时时间:默认 10 分钟
* 4.设置同时运行checkpoint最大数量
* 5.设置最小等待间隔:
* 上一轮 checkpoint 结束到下一轮 checkpoint 开始之间的间隔设置了 > 0 ,并发就会变成 1
* 6.设置取消作业时外部系统持久化会保留
* 7.设置checkpoint连续失败次数
* */
environment.enableCheckpointing(5000, CheckpointingMode.EXACTLY_ONCE);
CheckpointConfig checkpointConfig = environment.getCheckpointConfig();
checkpointConfig.setCheckpointStorage("hdfs://localhost:8020/path");
checkpointConfig.setCheckpointTimeout(60000); // 10 分钟
checkpointConfig.setMaxConcurrentCheckpoints(1);
checkpointConfig.setMinPauseBetweenCheckpoints(1000);
checkpointConfig.setExternalizedCheckpointCleanup(
CheckpointConfig.ExternalizedCheckpointCleanup.RETAIN_ON_CANCELLATION
);
checkpointConfig.setTolerableCheckpointFailureNumber(10);
/*
* TODO 非对齐检查点
* */
checkpointConfig.enableUnalignedCheckpoints();
checkpointConfig.setAlignedCheckpointTimeout(Duration.ofSeconds(1));
}
}
通用增量checkpoint
执行过程
- 带状态的算子任务将状态更改写入变更日志(记录状态)
- 状态物化:状态表定期保存,独立于检查点
- 状态物化完成后,状态变更就可以被截断到相应的点
保存点 Savepoint
一个存盘的备份,原理和算法于检查点相同,只是额外增加一些元数据。
保存点不会自动创建,必须由用户手动触发保存操作。
状态一致性
概念和级别
发生故障、需要恢复进行回滚时候需要更多保障机制
状态一致性的三种级别:最多一次、至少一次、精确一次
端到端的状态一致性
- 输入端:由于数据被消费之后就彻底不存在了,所以只能保证at-most-once的一致性语义。
- 解决方案:对数据进行持久化保存。Flink的Source任务中将数据读取的偏移量保存为状态,就可以在故障恢复时从检查点读取出来,对数据源重置偏移量,重新获得数据。
- 输出端:可能出现问题 —— 数据可能重复写入外部系统。
- 幂等写入:操作可重复执行很多次,但只导致一次结果更改。
- 事务写入:用一个事务进行数据向外部系统的写入,事务与检查点绑定在一起。保存状态的同时就开启一个事务,数据都写在这个事务中。
- 实现方式:
- 预写日志 WAL
- 两段式提交 2PC