摘要
在一些重要的flink数据加工场景中,实现Exactly Once(精确一次)的数据处理是必须的。Exactly Once意味着flink处理数据既能保证数据不丢失也能保证数据不重复。
整个flink处理链路大致分为 Source -> Transform -> Sink三个环节. 选用支持消息持久化和重置消费位点的kafka组件即可保证Source端的数据精确一次处理。依靠flink自身的checkpoint机制保证Transform阶段的数据精确一次处理。本文讨论选用支持事务的kafka实现Sink端的数据精确一次处理。
正文
基于flink1.13,使用官方提供的写入到kafka的FlinkKafkaProducer。为实现Exactly Once语义,flink程序需要如下相关配置:
//flink作业开启checkpoint
env.enableCheckpointing(interval);
//FlinkKafkaProducer
Properties producerpros = new Properties();
producerpros.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "xx:9092");
/*
* Flink 的 Kafka连接器中配置的事务超时时间 transaction.timeout.ms 默认是 1小时,
而Kafka集群配置的事务最大超时时间 transaction.max.timeout.ms 默认是 15 分钟。
* 这两个超时时间,前者应该小于等于后者。
* */
producerpros.put(ProducerConfig.TRANSACTION_TIMEOUT_CONFIG, 600000);
//创建flinkkafkaProducer
FlinkKafkaProducer flinkKafkaProducer = new FlinkKafkaProducer(
"topic",
new KafkaProducerSerializationSchema("topic"),
producerpros,
FlinkKafkaProducer.Semantic.EXACTLY_ONCE //EXACTLY_ONCE语义
);
(1)flink程序的相关配置及checkpoint流程
FlinkKafkaProducer通过继承TwoPhaseCommitSinkFunction间接实现了CheckpointedFunction, CheckpointListener两个接口。这意味着Sink算子(