2.Checkpoint
2.1. 状态的保存和修复
checkpoint
定时制作分布式快照,对程序中的状态进行备份
发生故障时:
将整个作业的所有task都回滚到最后一次成功checkpoint中的状态,然后从那个点开始处理
必要条件:
数据源支持重发
一致性语义:
恰好一次
至少一次
StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment(); env.enableCheckpointing(1000);
env.getCheckpointConfig().setCheckpointingMode(CheckpointingMode.EXACTLY_ONCE);
env.getCheckpointConfig().setMinPauseBetweenCheckpoints(500); env.getCheckpointConfig().setCheckpointTimeout(60000); env.getCheckpointConfig().setMaxConcurrentCheckpoints(1); env.getCheckpointConfig().enableExternalizedCheckpoints(ExternalizedCheckpointCleanup.RETAIN_ON_CANCELLATION);
2.2. 可选择的状态存储方式
state 的store和checkpoint的位置取决于stateBackend的配置
MemoryStateBackend
state的数据保存在java的堆内存中,执行checkpoint的时候,会把state快照的数据保存到jobManager的内存中
基于内存的,生产环境不建议使用
FsStateBackend
state的数据保存在taskManager的内存中,执行checkpoint的时候,会把state的快照数据保存到配置的文件系统中,可以使用HDFS等文件系统
RocksDBStateBackend
在本地文件系统中维护一个状态,state会直接写入本地RockDb中,同时他需要配置一个远端的filesystem uri(一般是HDFS),在做checkpoint的时候,会把本地的数据直接复制到filesystem中,fail over的时候从filesystem中恢复到本地.
RockDB克服了state受内存限制的缺点,同时又能持久化到远端的文件系统中,适合在生产场景使用。
状态存储方式 | MemoryStateBackend | FsStateBackend | RocksDBStateBackend |
---|---|---|---|
构造方法 | MemoryStateBackend(int maxStateSize,boolean asynchronousSnapshots ) | FsStateBackend(URI checkpointDataUri,boolean asynchronousSnapshots ) | RockDBStateBackend(URI checkpointDataUri,boolean asynchronousSnapshots ) |
存储方式 | State:TaskManager内存Checkpoint:JobManager内存 | state:TaskManager内存Checkpoint:外部文件系统(本地或HDFS) | state:TaskManager上的KV数据库(实际使用内存+磁盘)checkpoint:外部文件系统(本地或者HDFS) |
容量限制 | 单个State maxStateSize 默认5M, maxStateSize<akka.framesize 默认 10M, 总大小不超过jobManager内存 | 单TaskManager上State总量不超过它的内存,总大小不超过配置的文件系统容量 | 单TaskManager上State总量不超过它的内存+磁盘单key最大2G, 总大小不超过配置的文件系统容量 |
推荐使用的场景 | 本地测试;几乎无状态的作业,比如:ETL;JobManage不容易挂,或者挂掉影响不大的情况.不推荐在生产场景使用 | 常规使用状态的作业,例如:分钟级窗口聚合、join;需要开启HA的作业可以在生产场景使用 | 超大状态的作业,例如:天级窗口聚合;需要开启HA的作业,对状态读写性能要求不高的作业可以在生产场景使用 |
2.3.checkPoint vs savePoint
checkPoint
- 应用定时触发,用于保存状态,会过期
- 内部应用失败重启的时候使用
savePoint
- 用户手动执行,是指向Checkpoint的指针,不会过期
- 在升级的情况下使用
注意:为了能够在作业的不同版本之间以及 Flink 的不同版本之间顺利升级,强烈推荐程序员通过 uid(String) 方法手动的给算子赋予 ID,这些 ID 将用于确定每一个算子的状态范围。如果不手动给各算子指定 ID,则会由 Flink 自动给每个算子生成一个 ID。只要这些 ID 没有改变就能从保存点(savepoint)将程序恢复回来。而这些自动生成的 ID 依赖于程序的结构,并且对代码的更改是很敏感的。因此,强烈建议用户手动的设置 ID。
2.4.flink重启策略
- Flink支持不同的重启策略,以在故障发生时控制作业如何重启
- 集群在启动时会伴随一个默认的重启策略,在没有定义具体重启策略时会使用该默认策略。如果在工作提交时指定了一个重启策略,该策略会覆盖集群的默认策略
- 默认的重启策略可以通过 Flink 的配置文件 flink-conf.yaml 指定。配置参数 restart-strategy定义了哪个策略被使用。
- 常用的重启策略
1.固定间隔 (Fixed delay)
2.失败率 (Failure rate)
3.无重启 (No restart)
1.如果没有启用 checkpointing,则使用无重启 (no restart) 策略。
2.如果启用了 checkpointing,但没有配置重启策略,则使用固定间隔 (fixed-delay) 策略,其中 Integer.MAX_VALUE 参数是尝试重启次数.
3.重启策略可以在flink-conf.yaml中配置,表示全局的配置。也可以在应用代码中动态指定,会覆盖全局配置.