Kafka生产者等价性-恰好一次还是仅生产者事务就足够了?

时间:2019-08-02 07:28:59

标签: apache-kafka kafka-consumer-api kafka-producer-api reactive-kafka

摘自本文https://www.confluent.io/blog/transactions-apache-kafka/

使用配置为至少一次传递语义的香草Kafka生产者和消费者,一旦以以下方式处理语义,流处理应用程序可能会完全丢失:

  1. 由于内部重试,producer.send()可能导致消息B的重复写入。这由幂等的生产者解决,而不是本文其余部分的重点。

2。 我们可能会重新处理输入消息A,导致重复的B消息被写到输出中,这完全违反了一次处理语义。如果流处理应用程序在写入B之后但将A标记为已使用之前崩溃,则可能会发生重新处理。因此,当恢复时,它将再次消耗A并再次写入B,从而导致重复。

3。 最后,在分布式环境中,应用程序将崩溃或(更糟!)暂时失去与系统其余部分的连接。通常,新实例会自动启动以替换被认为丢失的实例。通过此过程,我们可能有多个实例处理相同的输入主题并写入相同的输出主题,从而导致输出重复,并且违反了一次处理语义的方式。我们称其为“僵尸实例”问题。

问题

在第二点,它提到当应用程序崩溃时,它将再次消耗A并写入B。但是生产商等权性是否已经解决了发送重复的这种情况?就像第一点一样?

点#3也会导致重复发送,#2和#3是否应该与#1成为同一问题?可以使用生产者幂等来处理?

1 个答案:

答案 0 :(得分:0)

幂等生产者仅在生产者的生存期内保证每个分区级别和语义一次。

因此它能够涵盖方案1)。

但是,如果生产者崩溃(甚至完全重启),这些保证将不再有效,就像您在2)和3)中所述,它可能会导致重复。

要解决2)和3),您可以使用事务生成器。它可以确保以原子方式处理和提交消息,因此,如果发生任何故障,中间的工作将被正确丢弃,因此新实例启动不会造成任何重复。同样,“僵尸”实例也将被适当地隔离,并防止完全违反一次语义。

权衡是保证/速度。交易生产者提供了更多的担保,但可能会对绩效产生影响。

无论如何,您选择哪个生产商取决于您的要求。请参阅文档的这两部分,并提供更多详细信息: