在kafka0.11版本之前是无法在kafka内实现exactly once 精确一次性保证的语义的,在0.11之后的版本,我们可以结合新特性 幂等性以及acks=-1 来实现kafka生产者的exactly once。
- acks=-1:在上面ack机制里已经介绍过,他能实现at least once语义,保证数据不会丢,但可能会有重复数据;
- 幂等性:0.11版本之后新增的特性,针对生产者,指生产者无论向broker 发送多少次重复数据,broker 只会持久化一条;
在0.11版本之前要实现exactly once语义只能通过外部系统如hbase的rowkey实现基于主键的去重。
幂等性解读:
在生产者配置文件 producer.properties 设置参数 enable.idompotence = true 即可启用幂等性。
Kafka的幂等性其实就是将原来需要在下游进行的去重操作放在了数据上游。开启幂等性的生产者在初始化时会被分配一个PID(producer ID),该生产者发往同一个分区(Partition)的消息会附带一个序列号(Sequence Number),Broker 端会对
事务:kafka在0.11 版本引入了事务支持。事务可以保证 Kafka 在 Exactly Once 语义的基础上,生产和消费可以跨分区和会话,要么全部成功,要么全部失败。
生产者事务:
Kafka引入了一个新的组件Transaction Coordinator,它管理了一个全局唯一的事务ID(Transaction ID),并将生产者的PID(幂等)和事务ID进行绑定,当生产者重启时虽然PID会变,但仍然可以和Transaction Coordinator交互,通过事务ID可以找回原来的PID,这样就保证了重启后的生产者也能保证Exactly Once 了。
同时,Transaction Coordinator 将事务信息写入 Kafka 的一个内部 Topic,即使整个kafka服务重启,由于事务状态已持久化到topic,进行中的事务状态也可以得到恢复,然后继续进行。
生产者事务主要是为了保证同一个事务中数据,写到不同分区的时候,都能成功全部写入,
如果只写入部分后宕机,重启后会有个问题:PID会发生改变,就不能保证这条事务的幂等性,
而开启事务后会根据事务id找到PID,然后重新写入,此时PID与之前一致,就能实现幂等性
那么数据不会重复吗,不会,因为kafka0.11版本后是支持幂等性(相同事务写入多次,结果相同)的。[