1、有状态算子
有状态:之前的结果
有状态计算:基于之前的结果进行的计算
代码演示与解析:
public class Demo01State {
public static void main(String[] args) throws Exception {
StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
DataStream<String> wordsDS = env.socketTextStream("master", 8888);
KeyedStream<String, String> kbDS = wordsDS.keyBy(word -> word);
/**
* process算子是flink提供的一个底层算子,可以获取到flink底层的状态,时间和数据
*/
DataStream<Tuple2<String, Integer>> countDS = kbDS
.process(new KeyedProcessFunction<String, String, Tuple2<String, Integer>>() {
//保存之前统计的结果(状态)
//问题:同一个task中数据共享一个count变量
// Integer count = 0;
//使用单词作为key,数量作为value
//问题:使用hashmap保存计算的中间结果,flink的checkpoint不会将hashmap中的数据持久化到hdfs总
//所以任务失败重启会丢失之前的结果
final HashMap<String,Integer> map = new HashMap<>();
/**
* processElement方法每一条数据执行一次
* @param word 一行数据
* @param ctx 上下文对象,可以获取到flink的key和时间属性
* @param out 用于将处理结果发送到下游
*/
@Override
public void processElement(String word,
KeyedProcessFunction<String, String, Tuple2<String, Integer>>.Context ctx,
Collector<Tuple2<String, Integer>> out) throws Exception {
//获取之前的结果
Integer count = map.getOrDefault(word,0);
//基于之前的结果进行计算
count++;
//将计算结果发送到下游
out.collect(Tuple2.of(word,count));
//通过map更新结果
map.put(word,count);
}
});
countDS.print();
env.execute();
}
}
2、CheckPoint
CheckPoint原理图解:
JobManager会定期向最前端的Source Task发送Checkpoint Trigger,然后barrier会在各个流传递,只要有task接触到了barrier之后就会同步进行快照到hdfs中去,当所有task处理完同一个barrier时就完成了一次checkpoint。
CheckPoint开启与使用:
在代码中单独开启
// 每 1000ms 开始一次 checkpoint
env.enableCheckpointing(5000);
// 高级选项:
// 当手动取消任务时,是否保留HDFS中保留hdfs中的快照
env.getCheckpointConfig().setExternalizedCheckpointCleanup(CheckpointConfig.ExternalizedCheckpointCleanup.RETAIN_ON_CANCELLATION);
//flink计算的状态会先保存在taskmanager中,当触发checkpoint时会将状态持久化到hdfs中
//指定状态在算子中保存的位置(状态后端)
//HashMapStateBackend:将状态保存在taskmanager的内存中
env.setStateBackend(new HashMapStateBackend());
//指定checkpoint保存快照的位置
env.getCheckpointConfig().setCheckpointStorage("hdfs://master:9000/flink/checkpoint");
在配置文件中统一开启
execution.checkpointing.interval: 5000
execution.checkpointing.externalized-checkpoint-retention: RETAIN_ON_CANCELLATION
execution.checkpointing.max-concurrent-checkpoints: 1
execution.checkpointing.min-pause: 0
execution.checkpointing.mode: EXACTLY_ONCE
execution.checkpointing.timeout: 10min
execution.checkpointing.tolerable-failed-checkpoints: 0
execution.checkpointing.unaligned: false
state.backend: hashmap
state.checkpoints.dir: hdfs://master:9000/flink/checkpoint
使用checkpoint
第一次提交任务直接提交
flink run -t yarn-session -p 3 -Dyarn.application.id=application_1717039073374_0009 -c com.shujia.flink.state.Demo5ExactlyOnceSInkKafka flink-1.0.jar
重启任务时基于hdfs中的快照重启
# -s 指定恢复任务的位置
flink run -t yarn-session -p 3 -Dyarn.application.id=application_1717039073374_0009 -c com.shujia.flink.state.Demo5ExactlyOnceSInkKafka -s hdfs://master:9000/flink/checkpoint/aa5c16e40767a315674780ba01a92fb3/chk-2 flink-1.0.jar