Flink Kafka两阶段提交理解

参考     https://zhuanlan.zhihu.com/p/111304281   

            https://developer.aliyun.com/article/720793

flink官网文档链接 https://flink.apache.org/features/2018/03/01/end-to-end-exactly-once-apache-flink.html 有些不是很容易翻译,就不再这里赘述

Kafka两阶段提交指的是FlinkKafkaProducer,也就是sink阶段

1. Two-Phase Commit(2PC)分为  提交请求(投票)提交(执行)两个阶段

2. Flink kafka的端到端exactly-once是基于kafka的事务来处理的

   kafka的producer事务处理在原生api中如下

//初始化事务控制
producer.initTransactions();

try {
//开启事务
     producer.beginTransaction();
     producer.send(record1);
     producer.send(record2);
 //提交事务
     producer.commitTransaction();
} catch (KafkaException e) {
//关闭事务
     producer.abortTransaction();
}

3. 在Flink KafkaProducer中继承了 TwoPhaseCommitSinkFunction 来实现两阶段提交的功能(要弄清楚两阶段分别干了什么事)

   该类下 有四个子类 

    protected abstract TXN beginTransaction() throws Exception;
    protected abstract void preCommit(TXN transaction) throws Exception;
    protected abstract void commit(TXN transaction);
    protected abstract void abort(TXN transaction);

beginTransaction():开始一个事务,返回事务信息的句柄
preCommit():预提交(即提交请求)阶段的逻辑
commit():正式提交阶段的逻辑
abort():取消事务

preCommit预提交阶段:

	@Override
	protected void preCommit(KafkaTransactionState transaction) throws FlinkKafka011Exception {
		switch (semantic) {
			case EXACTLY_ONCE:
			case AT_LEAST_ONCE:
				flush(transaction);
				break;
			case NONE:
				break;
			default:
				throw new UnsupportedOperationException("Not implemented semantic");
		}
		checkErroneous();
	}

其中,flush()方法实际上是代理了KafkaProducer.flush()方法

preCommit()方法是在TwoPhaseCommitSinkFunction.snapshotState()中被使用

此阶段将快照轮次与当前事务记录到一个 Map 表示的待提交事务集合中,key 是当前快照轮次的 CheckpointId,value 是由 TransactionHolder 表示的事务对象。TransactionHolder 对象内部记录了 transactionalId、producerId、epoch 以及 Kafka 客户端 kafkaProducer 的引用

持久化当前事务处理状态,也就是将当前处理的事务详情存入状态后端

commit提交阶段:

	@Override
	protected void commit(KafkaTransactionState transaction) {
		if (transaction.isTransactional()) {
			try {
				transaction.producer.commitTransaction();
			} finally {
				recycleTransactionalProducer(transaction.producer);
			}
		}
	}

commit()方法实际上是代理了KafkaProducer.commitTransaction()方法,正式向Kafka提交事务

该方法的调用点位于TwoPhaseCommitSinkFunction.notifyCheckpointComplete()方法中,当所有检查点都成功完成之后,会回调这个方法。

只有在所有检查点都成功完成这个前提下,写入才会成功。一旦有检查点失败,notifyCheckpointComplete()方法就不会执行。

如果重试也不成功的话,最终会调用abort()方法回滚事务

未commit()的数据在消费时默认也是可以消费到的,consumer消费者参数中

public static final String ISOLATION_LEVEL_CONFIG = "isolation.level";

//控制怎么读取事务性的消息,如果设置为 read_committed,  consumer.poll() 只会等待事务性消息被提交后才会继续消费

这个参数的默认值为 read_uncommitted

 

 

   

 

 

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Flink阶段提交是指在Flink中实现对外部系统的EXACTLY_ONCE语义的一种机制。在Flink中,通过使用TwoPhaseCommitSinkFunction接口来实现阶段提交。这个接口在FlinkKafka Producer的connector中得到了实现,从而支持了对外部Kafka Sink的EXACTLY_ONCE语义。\[3\] 具体实现上,Flink的TwoPhaseCommitSinkFunction接口代理了KafkaProducer的commitTransaction()方法,通过调用这个方法来向Kafka提交事务。\[2\]这样一来,Flink就能够保证在进行数据写入外部Kafka Sink时,实现了精确一次的语义,即每条数据只会被写入一次,不会出现重复写入或丢失的情况。 总结起来,Flink阶段提交机制通过使用TwoPhaseCommitSinkFunction接口和Kafka Producer的commitTransaction()方法来实现,从而保证了对外部Kafka Sink的EXACTLY_ONCE语义。这个机制能够确保数据的准确性和一致性,避免了数据重复写入或丢失的问题。 #### 引用[.reference_title] - *1* *3* [Flink阶段提交](https://blog.csdn.net/lisenyeahyeah/article/details/90288231)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [Flink阶段提交](https://blog.csdn.net/liuwei0376/article/details/126259056)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值