Apache flink Flink检查点模式ExactlyOnce未按预期工作
我是flink的新手,如果我的理解是错误的,我将构建一个数据流应用程序,并且该流包含多个数据流,这些数据流将检查传入数据流中是否存在必需的字段。我的应用程序验证传入的数据,如果数据验证成功,它应该将数据附加到给定文件中(如果数据已经存在)。我试图模拟一个数据流中是否发生任何异常,其他数据流不应受到影响,因为我在其中一个流中显式地抛出异常。为了简单起见,在下面的示例中,我使用windows文本文件来附加数据 注意:我的流没有状态,因为我没有任何东西要存储在状态中Apache flink Flink检查点模式ExactlyOnce未按预期工作,apache-flink,flink-streaming,flink-cep,Apache Flink,Flink Streaming,Flink Cep,我是flink的新手,如果我的理解是错误的,我将构建一个数据流应用程序,并且该流包含多个数据流,这些数据流将检查传入数据流中是否存在必需的字段。我的应用程序验证传入的数据,如果数据验证成功,它应该将数据附加到给定文件中(如果数据已经存在)。我试图模拟一个数据流中是否发生任何异常,其他数据流不应受到影响,因为我在其中一个流中显式地抛出异常。为了简单起见,在下面的示例中,我使用windows文本文件来附加数据 注意:我的流没有状态,因为我没有任何东西要存储在状态中 public class Exce
public class ExceptionTest {
public static void main(String[] args) throws Exception {
StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
// start a checkpoint every 1000 ms
env.enableCheckpointing(1000);
// env.setParallelism(1);
//env.setStateBackend(new RocksDBStateBackend("file:///C://flinkCheckpoint", true));
// to set minimum progress time to happen between checkpoints
env.getCheckpointConfig().setMinPauseBetweenCheckpoints(500);
// checkpoints have to complete within 5000 ms, or are discarded
env.getCheckpointConfig().setCheckpointTimeout(5000);
// set mode to exactly-once (this is the default)
env.getCheckpointConfig().setCheckpointingMode(CheckpointingMode.EXACTLY_ONCE);
// allow only one checkpoint to be in progress at the same time
env.getCheckpointConfig().setMaxConcurrentCheckpoints(1);
// enable externalized checkpoints which are retained after job cancellation
env.getCheckpointConfig().enableExternalizedCheckpoints(CheckpointConfig.ExternalizedCheckpointCleanup.RETAIN_ON_CANCELLATION); // DELETE_ON_CANCELLATION
env.setRestartStrategy(RestartStrategies.fixedDelayRestart(
3, // number of restart attempts
Time.of(10, TimeUnit.SECONDS) // delay
));
DataStream<String> input1 = env.fromElements("hello");
DataStream<String> input2 = env.fromElements("hello");
DataStream<String> output1 = input.flatMap(new FlatMapFunction<String, String>() {
@Override
public void flatMap(String value, Collector<String> out) throws Exception {
//out.collect(value.concat(" world"));
throw new Exception("=====================NO VALUE TO CHECK=================");
}
});
DataStream<String> output2 = input.flatMap(new FlatMapFunction<String, String>() {
@Override
public void flatMap(String value, Collector<String> out) throws Exception {
out.collect(value.concat(" world"));
}
});
output2.addSink(new SinkFunction<String>() {
@Override
public void invoke(String value) throws Exception {
try {
File myObj = new File("C://flinkOutput//filename.txt");
if (myObj.createNewFile()) {
System.out.println("File created: " + myObj.getName());
BufferedWriter out = new BufferedWriter(
new FileWriter("C://flinkOutput//filename.txt", true));
out.write(value);
out.close();
System.out.println("Successfully wrote to the file.");
} else {
System.out.println("File already exists.");
BufferedWriter out = new BufferedWriter(
new FileWriter("C://flinkOutput//filename.txt", true));
out.write(value);
out.close();
System.out.println("Successfully wrote to the file.");
}
} catch (IOException e) {
System.out.println("An error occurred.");
e.printStackTrace();
}
}
});
env.execute();
}
public class ExceptionTest {
public static void main(String[] args) throws Exception {
StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
// start a checkpoint every 1000 ms
env.enableCheckpointing(1000);
// env.setParallelism(1);
//env.setStateBackend(new RocksDBStateBackend("file:///C://flinkCheckpoint", true));
// to set minimum progress time to happen between checkpoints
env.getCheckpointConfig().setMinPauseBetweenCheckpoints(500);
// checkpoints have to complete within 5000 ms, or are discarded
env.getCheckpointConfig().setCheckpointTimeout(5000);
// set mode to exactly-once (this is the default)
env.getCheckpointConfig().setCheckpointingMode(CheckpointingMode.EXACTLY_ONCE);
// allow only one checkpoint to be in progress at the same time
env.getCheckpointConfig().setMaxConcurrentCheckpoints(1);
// enable externalized checkpoints which are retained after job cancellation
env.getCheckpointConfig().enableExternalizedCheckpoints(CheckpointConfig.ExternalizedCheckpointCleanup.RETAIN_ON_CANCELLATION); // DELETE_ON_CANCELLATION
env.setRestartStrategy(RestartStrategies.fixedDelayRestart(
3, // number of restart attempts
Time.of(10, TimeUnit.SECONDS) // delay
));
DataStream<String> input1 = env.fromElements("hello");
DataStream<String> input2 = env.fromElements("hello");
DataStream<String> output1 = input.flatMap(new FlatMapFunction<String, String>() {
@Override
public void flatMap(String value, Collector<String> out) throws Exception {
//out.collect(value.concat(" world"));
throw new Exception("=====================NO VALUE TO CHECK=================");
}
});
DataStream<String> output2 = input.flatMap(new FlatMapFunction<String, String>() {
@Override
public void flatMap(String value, Collector<String> out) throws Exception {
out.collect(value.concat(" world"));
}
});
String outputPath = "C://flinkCheckpoint";
final StreamingFileSink<String> sink = StreamingFileSink
.forRowFormat(new Path(outputPath), new SimpleStringEncoder<String>("UTF-8"))
.withRollingPolicy(
DefaultRollingPolicy.builder()
.withRolloverInterval(TimeUnit.MINUTES.toMillis(15))
.withInactivityInterval(TimeUnit.MINUTES.toMillis(5))
.withMaxPartSize(1)
.build())
.build();
output2.addSink(sink);
});
env.execute();
}
公共类例外测试{
公共静态void main(字符串[]args)引发异常{
StreamExecutionEnvironment env=StreamExecutionEnvironment.getExecutionEnvironment();
//每1000毫秒启动一个检查点
环境启用检查点(1000);
//环境(一);
//环境设置状态后端(新RocksDBState后端(“file:///C://flinkCheckpoint“,对”);
//设置检查点之间的最小进度时间
env.getCheckpointConfig().setMinPausebetween检查点(500);
//检查点必须在5000毫秒内完成,否则将被丢弃
env.getCheckpointConfig().setCheckpointTimeout(5000);
//将模式设置为恰好一次(这是默认设置)
env.getCheckpointConfig().setCheckpointingMode(CheckpointingMode.justice_ONCE);
//同时只允许一个检查点进行
env.getCheckpointConfig().setMaxConcurrentCheckpoints(1);
//启用作业取消后保留的外部化检查点
env.getCheckpointConfig().enableExternalizedCheckpoints(CheckpointConfig.ExternalizedCheckpointCleanup.RETAIN_ON_CANCELLATION);//删除_ON_CANCELLATION
环境setRestartStrategy(restartStrategys.fixedDelayRestart(
3,//重新启动尝试次数
Time.of(10,TimeUnit.SECONDS)//延迟
));
DataStream input1=env.fromElements(“hello”);
DataStream input2=env.fromElements(“你好”);
DataStream output1=input.flatMap(新的flatMap函数(){
@凌驾
公共void flatMap(字符串值,收集器输出)引发异常{
//out.collect(value.concat(“世界”));
抛出新异常(“==============================================================================================”);
}
});
DataStream output2=input.flatMap(新的flatMap函数(){
@凌驾
公共void flatMap(字符串值,收集器输出)引发异常{
out.collect(value.concat(“世界”));
}
});
字符串outputPath=“C://flinkCheckpoint”;
最终StreamingFileSink接收器=StreamingFileSink
.forRowFormat(新路径(outputPath)、新SimpleStringEncoder(“UTF-8”))
.使用滚动策略(
DefaultRollingPolicy.builder()
.带滚动区间(时间单位为分钟,单位为分钟(15))
.withInactivityInterval(时间单位。分钟。托米利斯(5))
.最大零件尺寸(1)
.build())
.build();
输出2.添加接收器(接收器);
});
execute();
}
但是当我检查Checkpoint文件夹时,我可以看到它创建了四个部分的文件,如下所示
我之所以这么做是因为它创建了多部分文件吗?为了保证端到端的精确一次记录传递(除了精确一次的状态语义之外),数据接收器需要参与检查点机制(以及数据源) 如果要将数据写入文件,则可以使用,它将其输入元素发送到bucket中的
文件系统
文件。这与检查点机制集成在一起,以提供完全现成的语义
如果要实现自己的接收器,那么接收器函数必须实现CheckpointedFunction
接口,并正确实现snapshotState(FunctionSnapshotContext上下文)
方法,该方法在请求检查点的快照并刷新当前应用程序状态时调用。此外,我建议实现CheckpointListener
接口,一旦分布式检查点完成,就会收到通知
Flink已经提供了一个抽象的TwoPhaseCommitSinkFunction
,它是所有打算实现一次语义的SinkFunction
的推荐基类。它通过在CheckpointedFunction
和
检查点侦听器
。例如,您可以有一个
public class ExceptionTest {
public static void main(String[] args) throws Exception {
StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
// start a checkpoint every 1000 ms
env.enableCheckpointing(1000);
// env.setParallelism(1);
//env.setStateBackend(new RocksDBStateBackend("file:///C://flinkCheckpoint", true));
// to set minimum progress time to happen between checkpoints
env.getCheckpointConfig().setMinPauseBetweenCheckpoints(500);
// checkpoints have to complete within 5000 ms, or are discarded
env.getCheckpointConfig().setCheckpointTimeout(5000);
// set mode to exactly-once (this is the default)
env.getCheckpointConfig().setCheckpointingMode(CheckpointingMode.EXACTLY_ONCE);
// allow only one checkpoint to be in progress at the same time
env.getCheckpointConfig().setMaxConcurrentCheckpoints(1);
// enable externalized checkpoints which are retained after job cancellation
env.getCheckpointConfig().enableExternalizedCheckpoints(CheckpointConfig.ExternalizedCheckpointCleanup.RETAIN_ON_CANCELLATION); // DELETE_ON_CANCELLATION
env.setRestartStrategy(RestartStrategies.fixedDelayRestart(
3, // number of restart attempts
Time.of(10, TimeUnit.SECONDS) // delay
));
DataStream<String> input1 = env.fromElements("hello");
DataStream<String> input2 = env.fromElements("hello");
DataStream<String> output1 = input.flatMap(new FlatMapFunction<String, String>() {
@Override
public void flatMap(String value, Collector<String> out) throws Exception {
//out.collect(value.concat(" world"));
throw new Exception("=====================NO VALUE TO CHECK=================");
}
});
DataStream<String> output2 = input.flatMap(new FlatMapFunction<String, String>() {
@Override
public void flatMap(String value, Collector<String> out) throws Exception {
out.collect(value.concat(" world"));
}
});
String outputPath = "C://flinkCheckpoint";
final StreamingFileSink<String> sink = StreamingFileSink
.forRowFormat(new Path(outputPath), new SimpleStringEncoder<String>("UTF-8"))
.withRollingPolicy(
DefaultRollingPolicy.builder()
.withRolloverInterval(TimeUnit.MINUTES.toMillis(15))
.withInactivityInterval(TimeUnit.MINUTES.toMillis(5))
.withMaxPartSize(1)
.build())
.build();
output2.addSink(sink);
});
env.execute();
}