一. kafka事务提交流程
1.Transaction ID
为了实现跨分区跨跨会话的事务,需要引入一个全局唯一的Transaction ID,并将生产者获得的id和Transaction ID绑定。这样当生产者重启后可以通过正在进行的Transaction ID获取原来的id
2.Transaction Coordinator
transaction coordinator(事务协调者)是运行在每个 kafka broker 上的一个模块,是 kafka broker 进程承载的新功能之一。transaction coordinator负责分配PID和管理事务以及读写Transaction log。
3.Transaction log
transaction log 是 kafka 的一个内部 topic,transaction log 有多个分区,每个分区都有一个 leader,该 leade对应哪个 kafka broker,哪个 broker 上的 transaction coordinator 就负责对这些分区的写操作。transaction log 存储事务的最新状态和其相关元数据信息。
- 生产者向任意kafka服务器发起请求获取相应事务协调者的地址。
- 生产者通过指定的TID向事务协调者请求PID,若TID存在返回PID,不存在新建一个PID。每次请求TID,TID会加上一个Epoch值,防止旧的生产者因为宕机重启后重试事务,造成事务重复。
- 生产者将消息存储的分区信息发给事务协调者,事务协调者将分区信息持久化。
- 生产者向对应分区发送消息。
- 生产者发起提交(commit)或者回滚请求(abort),事务协调者持久化该请求,标记为准备状态。
- 事务协调者向分区发送提交或者回滚请求,分区执行完成后返回结果。
- 事务协调者将处理结果持久化。
二. 代码演示
Kafka 的事务一共有涉及以下5个API
// 1 初始化事务
void initTransactions();
// 2 开启事务
void beginTransaction() throws ProducerFencedException;
// 3 在事务内提交已经消费的偏移量(主要用于消费者)
void sendOffsetsToTransaction(Map<TopicPartition, OffsetAndMetadata> offsets,
String consumerGroupId) throws
ProducerFencedException;
// 4 提交事务
void commitTransaction() throws ProducerFencedException;
// 5 放弃事务(类似于回滚事务的操作)
void abortTransaction() throws ProducerFencedException;
下面以生产者为例演示事务消息
import org.apache.kafka.clients.producer.KafkaProducer;
import org.apache.kafka.clients.producer.ProducerConfig;
import org.apache.kafka.clients.producer.ProducerRecord;
import org.apache.<