1.至少一次(At Least Once)= ACK级别设置为-1 + 分区副本大于等于2 + ISR里应答的最小副本数量大于等于2
2.最多一次(At Most Once)= ACK级别设置为0
3.精确一次(Exactly Once):对于一些非常重要的信息,比如和钱相关的数据,要求数据既不能重复也不丢失。
优缺点:At Least Once可以保证数据不丢失,但是不能保证数据不重复;
At Most Once可以保证数据不重复,但是不能保证数据不丢失。
Exactly Once--幂等性和事务可以保障数据精确一次
4.Kafka 0.11版本以后,引入了一项重大特性:幂等性和事务。
5.幂等性
1)原理
幂等性就是指Producer不论向Broker发送多少次重复数据,Broker端都只会持久化一条,保证了不重复。
举例: 订单支付--> 用户付款--调用支付宝接口-->回写订单数据--> 发起一个异步线程,用于修改订单数据。 此时会遇到一个问题,支付的订单修改状态,修改了两次。
精确一次(Exactly Once) = 幂等性 + 至少一次( ack=-1 + 分区副本数>=2 + ISR最小副本数量>=2) 。
重复数据的判断标准:具有<PID, Partition, SeqNumber>相同主键的消息提交时,Broker只会持久化一条。其 中PID是Kafka每次重启都会分配一个新的;Partition 表示分区号;Sequence Number是单调自增的。
所以幂等性只能保证的是在单分区单会话内不重复。
如果kafka集群挂了,重启了,此时以前的数据还会发送一回,数据又重复了。
2)如何使用
开启参数 enable.idempotence 默认为 true,false 关闭。
6.生产者事务
使用原因:幂等性只能保障服务器不挂掉的情况下,发送数据是唯一的,假如发送者服务器挂掉了,那么重启之后还是会发送重复的数据,所以需要使用事务。
1)kafka事务原理
每一个broker都有一个事务协调器
2)共有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;
3)单个生产者,使用事务保证消息的仅一次发送