前言
现在假定这么一个业务场景,从kafka中的topic获取消息数据,经过一定加工处理后,发送到另外一个topic中,要求整个过程消息不能丢失,也不能重复发送,即实现端到端的Exactly-Once精确一次消息投递。这该如何实现呢?
kafka事务介绍
针对上面的业务场景,kafka已经替我们想到了,在kafka 0.11版本以后,引入了一个重大的特性:幂等性和事务。
幂等性
这里提到幂等性的原因,主要是因为事务的启用必须要先开启幂等性,那么什么是幂等性呢?
幂等性是指生产者无论向kafka broker发送多少次重复的数据,broker 端只会持久化一条,保证数据不会重复。
幂等性通过生产者配置项enable.idempotence=true开启,默认情况下为true。
幂等性实现原理
- 每条消息都有一个主键,这个主键由 <PID, Partition, SeqNumber>组成。
- PID:ProducerID,每个生产者启动时,Kafka 都会给它分配一个 ID,ProducerID 是生产者的唯一标识,需要注意的是,Kafka 重启也会重新分配 PID。
- Partition:消息需要发往的分区号。
- SeqNumber:生产者,他会记录自己所发送的消息,给他们分配一个自增的 ID,这个 ID 就是 SeqNumber,是该消息的唯一标识,每发送一条消息,序列号加 1。
- 对于主键相同的数据,kafka 是不会重复持久化的,它只会接收一条。
幂等性缺点
根据幂等性的原理,我们发现它存在下面的缺点:
- 只能保证单分区、单会话内的数据不重复
- kafka 挂掉,重新给生产者分配了 PID,还是有可能产生重复的数据 <