Kafka生产者的幂等和事务

Kafka从0.11版本开始支持幂等和事务性生产者,增强了消息传递的准确性和一致性。幂等生产者确保在重试情况下不引入重复消息,而事务性生产者则允许原子性地跨多个分区和主题发送消息。要启用幂等,需设置`enable.idempotence=true`;启用事务需设置`transactional.id`。注意,正确配置主题的复制因子和in-sync副本数以保证事务性。事务生产者使用异常处理错误,所有在beginTransaction和commitTransaction之间的消息都属于同一事务。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

从kafka0.11开始,KafkaProducer又支持两者模式,幂等生产者和事务生产者。幂等生产者加强了kafka的交付语义,从至少一次交付到精确一次交付。特别是生产者的重试将不再引入重复。事务性生产者允许应用程序原子性地将消息发送到多个分区(和主题)。

幂等

要启动幂等,必须将enable.idempotence配置为true。如果设置了,则retries(重试)配置将默认为Integer.MAX_VALUE,acks配置将默认为all。API没有变化,所以无需修改现有应用程序即可利用此功能。

此外,如果send(ProducerRecord)即使在无限次重试的情况下也会返回错误(例如消息在发送前在缓冲区中过期),那么建议关闭生产者,并检查最后产生的消息的内容,以确保它不重复。

最后,生产者只能保证单个会话内发送的消息的幂等性。

事务

要使用事务生产者和attendant API,必须设置transactional.id。如果设置了transactional.id,幂等性会和幂等所依赖的生产者配置一起自动启用。此外,应该对包含在事务中的topic进行耐久性配置。特别是,replication.factor应该至少是3,而且这些topic的min.insync.replicas应该设置为2。最后,为了实现从端到端的事务性保证,消费者也必须配置为只读取已提交的消息。

transactional.id的目的是实现单个生产者实例的多个会话之间的事务恢复。它通常是由分区、有状态的应用程序中的分片标识符派生的。因此,它对于在分区应用程序中运行的每个生产者实例来说应该是唯一的。

Properties props = new Properties();
props.put("bootstrap.servers", "localhost:9092");
props.put("transactional.id", "my-transactional-id");
Producer<String, String> producer = new KafkaProducer<>(props, new StringSerializer(), new StringSerializer());

producer.initTransactions();

try {
    producer.beginTransaction();
    for (int i = 0; i < 100; i++)
        producer.send(new ProducerRecord<>("my-topic", Integer.toString(i), Integer.toString(i)));
    producer.commitTransaction();
} catch (ProducerFencedException | OutOfOrderSequenceException | AuthorizationException e) {
    // We can't recover from these exceptions, so our only option is to close the producer and exit.
    producer.close();
} catch (KafkaException e) {
    // For all other exceptions, just abort the transaction and try again.
    producer.abortTransaction();
}
producer.close();

如示例所示,每个生产者只能有一个未完成的事务。在beginTransaction()和commitTransaction()调用之间发送的所有消息都将是单个事务的一部分。当指定transactional.id时,生产者发送的所有消息都必须是事务的一部分。

事务生产者使用异常来传递错误状态。特别是,不需要为producer.send()指定回调,也不需要在返回的Future上调用.get():如果任何producer.send()或事务性调用在事务过程中遇到不可恢复的错误,就会抛出KafkaException。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值