flink-kafka端到端精准一次性
//FlinkKafkaProducer 默认不读取全局配置而是写死默认值AT_LEAST_ONCE 在创建KafkaProducer时要指定时间语义 详见: new FlinkKafkaProducer<>()
Optional<FlinkFixedPartitioner<String>> customPartitioner = Optional.of(new FlinkFixedPartitioner<>());
flinkKafkaProducer = new FlinkKafkaProducer<>(topic,
new SimpleStringSchema(),
producerProp,
customPartitioner.orElse(null),
FlinkKafkaProducer.Semantic.EXACTLY_ONCE,
DEFAULT_KAFKA_PRODUCERS_POOL_SIZE);
//生产者的事务超时属性 使用EXACTLY_ONCE需要增加
producerProp.put(ProducerConfig.TRANSACTION_TIMEOUT_CONFIG, 1000 * 60 * 5);
//设置事务ID,这里用了类名做唯一ID
producerProp.put(ProducerConfig.TRANSACTIONAL_ID_CONFIG, getClassName());
//开启幂等性
producerProp.put(ProducerConfig.ENABLE_IDEMPOTENCE_CONFIG,"true");
producerProp.put(ProducerConfig.MAX_IN_FLIGHT_REQUESTS_PER_CONNECTION,"5");
//设置为读已提交
consumerProp.setProperty(ConsumerConfig.ISOLATION_LEVEL_CONFIG,"read_committed");
- 中间有checkpoint 所以flink整合kafka 可以实现完整的精准一次性
- 注意: flink-kafka精准一次的致命弱点: 在进行checkpoint时才会将数据提交到kafka,导致 流处理会转换成微批处理(微批的大小为checkpoint的间隔时间)
代码样例
pom.xml
- 特别注意如果是本地只用导入flink-connector-kafka_2.12即可
- 如果是flink集群上需要导入以下三个包才能正常使用kafka 因为flink-connector-kafka包中把后面两个排除掉了
- flink-connector-kafka_2.12-1.12.0
- flink-connector-kafka-base_2.12-1.12.0
- kafka-clients-2.2.0
<dependency>
&l