Flink中的“Exactly Once”语义是什么,如何保证?

Flink的“Exactly Once”语义指的是在流处理过程中,每条记录只被执行一次,没有重复执行和丢失。

Flink通过以下机制来保证Exactly Once语义:

  1. Checkpoint机制。将流处理状态和运算位置定期保存到Checkpoint,发生失败后可以从Checkpoint恢复继续执行。
  2. Write Ahead Log。将输出先写入WAL,然后再提交到下游系统。发生失败可以从WAL恢复丢失的数据。
  3. 事务提交协议。输出操作使用两阶段提交协议,要么完全成功要么完全失败,保证没有部分提交。
  4. 幂等Sink。使用可以重复调用的Sink,同一记录的多次输出只会执行一次。

下面通过一个例子来说明:

StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
env.enableCheckpointing(5000);  // 每5秒钟开启一次Checkpoint

DataStream<String> stream = env.socketTextStream("localhost", 9999);

// 用作Sink的Kafka Producer
FlinkKafkaProducer010<String> kafkaSink = new FlinkKafkaProducer010<String>("brokerList", "outputTopic", 
    new SimpleStringSchema());

stream.addSink(kafkaSink); 

env.execute();

这个例子从Socket读取数据,发送到Kafka的outputTopic主题。它使用了:

  1. env.enableCheckpointing(5000)启用了5秒Checkpoint间隔,来保存状态和运算位置。
  2. FlinkKafkaProducer010这个Sink使用了两阶段提交和幂等语义,来保证Exactly Once输出。
  3. Kafka本身也具有异常时数据重复传输的机制,可以与Checkpoint机制互相配合。

这样,整个程序既具有Checkpoint来保证Exactly Once语义,又使用幂等Sink和Kafka来确保输出的Exactly Once。