kafka如何保证消息交付可靠性以及避免消息重复

消息交付可靠性

什么是消息交付可靠性

  所谓的消息交付可靠性保障,是指Kafka为Producer和Consumer要处理的消息提供了什么样的承诺。常见的承诺右三种:

  • 最多一次:消息可能丢失,但绝不会被重新发送。
  • 至少一次:消息不会丢失,但有可能被重复发送。
  • 精确一次:消息不会丢失,也不会被重新发送。

   kafka默认是使用第二种”至少一次”,因为只有Broker成功“提交”消息且Producer接到Broker的应答才会认为该消息成功发送。如果此时,消息提交成功了,但是Broker的应答没有成功返回Producer端(比如发生了网络抖动),那么Producer就无法确定是否发送成功。因此它只能选择重试,此时就会导致消息重复发送。
  kafka也可以提供最多一次交付保障,只需要让Producer禁止重试即可。通常情况下我们是不希望出现消息丢失的,但是有一些场景里偶尔的消息丢失是被允许的,不过消息重复是被绝对禁止的。此时使用最多一次交付保障就是比较好的。
  kafka是如何做到精确一次的?它是通过两种机制:幂等性和事务完成的。

什么是幂等性

  幂等性指:某些操作或函数能够执行多次,但每次的结果都是不变的。举例任何数乘以1就是一个幂等操作,因为一个数乘以1一次和任意次的结果相同。
在这里插入图片描述
  幂等性的最大优势在于我们可以安全的重试任何幂等性操作。

幂等性Producer

  在kafka中,Producer默认不是幂等性的,但我们可以创建幂等性的Producer。指定Producer幂等性的方法很简单,只需要设置一个参数:props.put(“enable.idempotence”,true)或props.put(ProducerConfig.ENABLE_IDEMPOTENCE_CONFIG,true)。
  之后kafka会自动帮我们做消息去重,底层原理很简单,是经典的用空间换时间的优化思路,即在Broker端多保存一些字段。

幂等性Producer的作用范围

  首先:他只能保证单分区上的幂等性,即一个幂等性Producer能够保证某个主题的一个分区上不能出现重复,不能保证多个分区的幂等性。其次:他只能实现单会话上的幂等性,不能实现跨会话的幂等性。也就是重启Producer进程后幂等性保证就消失了。

如何实现多分区多会话的消息无重复?

  使用事务,或者依赖事务型Producer

kafka事务

  kafka主要在读已提交的隔离级别下工作。它能保证多条消息原子性的写入目标分区,也能保证Consumer只能看到事务成功提交的消息。

事务型Producer

  它能保证将消息原子性的写入多个分区中,并且不惧怕进程重启,重启之后还能保证发送消息的精确一次处理。
  设置事务Producer方法:

  • 设置enable.idempotence = true
  • 设置Producer端参数transactional.id
    代码使用:

producer.initTransactions();
try {
            producer.beginTransaction();
            producer.send(record1);
            producer.send(record2);
            producer.commitTransaction();
} catch (KafkaException e) {
            producer.abortTransaction();
}

使用了事务Producer之后就要有事务的开启,提交回滚等东西了。
之后Consumer端也需要做一些修改:设置Consumer端的参数isolation.level参数的值。
它的取值有:
1:read_uncommitted:读未提交
2:read_committed:读已提交

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值