1、Stateful Operations 有状态算子:
有状态计算,使用到前面的数据,常见的有状态的算子:例如sum、reduce,因为它们在计算的时候都是用到了前面的计算的结果
总结来说,有状态计算并不是独立存在的,每一次的计算都与前面的数据是有关系的。所有的聚合算子都是有状态算子。
2、CheckPoint:
1、CheckPoint:定时将Flink的计算的状态持久化到Hdfs上,如果Flink的任务失败可以基于Hdfs中保存的状态恢复任务,能够保证任务的计算状态不丢失。checkpoint可以维护TB级别的计算状态。
2、Fllink会将计算状体存储两份,一份是存储在Flink内存中,放在内存中是为了获取查询更新,因为Flink在处理数据的是过程中,计算状态会改变,第二份是通过CheckPoint将计算状态持久化的存储到Hdfs中,这样可以保证Flink任务失败的时候可以基于Hdfs中存储的计算状态恢复任务。
总结:就是原先Flink的计算的状态是存储在内存中,但是为了防止计算状态丢失,就将Flink的计算状态持久化到Hdfs中。当任务中途失败后,找到最新的一个checkpoint,基于这个checkpoint中存储的数据作为计算状态恢复任务。
3、CheckPoint的开启方式:
1、在代码中单独开启checkpoint:
// 每 10000ms 开始一次 checkpoint
env.enableCheckpointing(10000)
// 高级选项:
// 设置模式为精确一次 (这是默认值)
env.getCheckpointConfig.setCheckpointingMode(CheckpointingMode.EXACTLY_ONCE)
// 确认 checkpoints 之间的时间会进行 500 ms
env.getCheckpointConfig.setMinPauseBetweenCheckpoints(500)
// Checkpoint 必须在一分钟内完成,否则就会被抛弃
env.getCheckpointConfig.setCheckpointTimeout(60000)
// 允许两个连续的 checkpoint 错误
env.getCheckpointConfig.setTolerableCheckpointFailureNumber(2)
// 同一时间只允许一个 checkpoint 进行
env.getCheckpointConfig.setMaxConcurrentCheckpoints(1)
// 使用 externalized checkpoints,这样 checkpoint 在作业取消后仍就会被保留
env.getCheckpointConfig.setExternalizedCheckpointCleanup(
ExternalizedCheckpointCleanup.RETAIN_ON_CANCELLATION)
//增量快照
env.setStateBackend(new EmbeddedRocksDBStateBackend(true))
//将状态保存到hdfs中
env.getCheckpointConfig.setCheckpointStorage("hdfs://master:9000/file/checkpoint")
public class Demo01CheckPoint {
public static void main(String[] args) throws Exception{
/**
* 使用checkpoint来保存计算状态
*/
//构建Flink环境:
StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
//开socket
DataStreamSource<String> lineDS = env.socketTextStream("master", 8888);
//开启checkpoint
//指定10秒拍一次checkpoint
env.enableCheckpointing(10000);
//使用 externalized checkpoints,这样 checkpoint 在作业取消后仍就会被保留
env.getCheckpointConfig().setExternalizedCheckpointCleanup(
CheckpointConfig.ExternalizedCheckpointCleanup.RETAIN_ON_CANCELLATION);
//将计算状态保存到hdfs中
env.getCheckpointConfig().setCheckpointStorage("hdfs://master:9000/file/checkpoint");
//指定计算状态在Flink中的存储的位置:是基于磁盘还是存储在内存中
//HashMapStateBackend(),表示的是数据存储在Flink的内存中
env.setStateBackend(new HashMapStateBackend());
//做wordCount
SingleOutputStreamOperator<String> wordDS = lineDS.flatMap((line, out) -> {
String[] split = line.split(",");
for (String word : split) {
//将数据循环发送到下游:
out.collect(word);
}
},Types.STRING);
//将上游传输过来的数据构建成kv形式的数据:
SingleOutputStreamOperator<Tuple2<Object, Integer>> mapDS = wordDS.map(word -> Tuple2.of(word, 1), Types.TUPLE(Ty