Flink自定义Sink系列之FileSink
文章目录
前言
本次主要记录flink关于checkpoint的一个简单的模拟的例子,便于后续直接回顾可以轻松回顾
一、编写FlinkSetEnv工具类
这里我们编写一个通用的flinkenv相关创建时候的公共工具类,包含从配置文件中设置并行度,开启checkpoint,设置状态后端
1.1FlinkSetEnv工具类
public class FlinkSetEnv {
//无参构造
public FlinkSetEnv(){
}
public static void CkAndStateBackend(StreamExecutionEnvironment env, String StateBackend, ParameterTool parameterTool) throws Exception {
if(env != null){
//设置并行度
env.setParallelism(parameterTool.getInt("Parallelism"));
//设置状态后端
if("FS".equals(StateBackend)){
env.setStateBackend(new FsStateBackend(parameterTool.get("state.backend.path","hdfs://cxxxx")));//最好在flink全局配置文件里设置
}else if("RocksDB".equals(StateBackend)){
env.setStateBackend(new RocksDBStateBackend(parameterTool.get("state.backend.path","hdfs://xxxx"),true));//第二个参数是开启增量模式
}else {
env.setStateBackend(new MemoryStateBackend());
}
//设置重启策略
env.setRestartStrategy(RestartStrategies.fixedDelayRestart(parameterTool.getInt("restart.times",5),parameterTool.getLong("delayBetweenAttempts")));
//开启checkpoint
env.getCheckpointConfig().isCheckpointingEnabled();
//设置cancel时保留Checkpoint
env.getCheckpointConfig().enableExternalizedCheckpoints(CheckpointConfig.ExternalizedCheckpointCleanup.RETAIN_ON_CANCELLATION);
//设置check模式为有且只有一次
env.getCheckpointConfig().setCheckpointingMode(CheckpointingMode.EXACTLY_ONCE);
//设置checkpoint时间间隔
env.getCheckpointConfig().setCheckpointInterval(parameterTool.getLong("checkpoint.interval"));
}else {
throw new Exception("env is null");
}
}
}
二、wordscount案例模拟checkpoint
2.1 主体测试类
代码如下(示例):
public class CheckPointTest {
public static void main(String[] args) throws Exception {
//1.创建流式执行环境
StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
//2.获取相关配置文件
InputStream resourceAsStream = CheckPointTest.class.getResourceAsStream("/config.properties");
ParameterTool parameterTool = ParameterTool.fromPropertiesFile(resourceAsStream);
env.getConfig().setGlobalJobParameters(parameterTool);//把全局配置文件夹在到环境中,便于后面上下文中可以使用
//3.设置并行度,状态后端以及checkpoint等策略
FlinkSetEnv.CkAndStateBackend(env,"Other",parameterTool);
//4.source
DataStreamSource<String> sourceDataStream = env.socketTextStream("localhost", 7777);
//5.转换成元组的形式
SingleOutputStreamOperator<Tuple2<String,Integer>> tupleStream = sourceDataStream.map(new MapFunction<String, Tuple2<String, Integer>>() {
@Override
public Tuple2<String, Integer> map(String value) throws Exception {
if("error".equals(value)){
throw new Exception("error is coming");
}
return new Tuple2<>(value,1);
}
});
//6.按照第一个元素进行分组,求和
SingleOutputStreamOperator<Tuple2<String, Integer>> resultStream = tupleStream.keyBy(new KeySelector<Tuple2<String, Integer>, String>() {
@Override
public String getKey(Tuple2<String, Integer> tuple2) throws Exception {
return tuple2.f0;
}
}).reduce(new ReduceFunction<Tuple2<String, Integer>>() {
@Override
public Tuple2<String, Integer> reduce(Tuple2<String, Integer> value1, Tuple2<String, Integer> value2) throws Exception {
return new Tuple2<>(value1.f0, value1.f1 + value2.f1);
}
});
//7.sink
resultStream.print();
//8.执行任务
env.execute("Test ChechPoint");
}
}
2.2 测试结果
总结
以上就是对flinkcheckpoint的简单测试,我们首先编写了一个公共工具类,用来统一加载env环境,然后通过配置文件流来设置一些公共的属性后,我们编写了一个简单的单词计数的测试类,这里我们模拟假定error来了的时候就要抛出异常,程序中断,但是我们设置了重启策略为两次,模拟了checkpoint的情况,可以看到,第一次,第二次重启的时候都可以从历史的状态中恢复,以至于我们的数据不会丢失,后面第三次的时候,程序便会直接失败,退出了!