具有 EXACTLY_ONCE_V2 的 Kafka Streams:InvalidProducerEpochException:生产者尝试使用旧纪元进行生产

cla*_*lay 5 apache-kafka apache-kafka-streams

这是一个简单、普通的 Kafka Streams 应用程序,使用EXACTLY_ONCE_V2.

configurationParameters.put(StreamsConfig.PROCESSING_GUARANTEE_CONFIG, StreamsConfig.EXACTLY_ONCE_V2);
Run Code Online (Sandbox Code Playgroud)

我看到的错误如下。如果我删除上面提到的 EXACTLY_ONCE_V2 设置,此错误就会消失,并且流应用程序运行数天不会出现错误。错误日志是:

[错误] 2021-11-27 18:10:23.141 [kafka-生产者-网络线程 | id-mapping-app-1eede139-ace6-4aff-9e94-ca508cb9c98d-StreamThread-1-生产者] RecordCollectorImpl - 流线程 [id-mapping-app-1eede139-ace6-4aff-9e94-ca508cb9c98d-StreamThread-1] 任务 [ 0_11] 将记录发送到任务 0_11 的主题数据记录输出时遇到错误,原因是:org.apache.kafka.common.errors.InvalidProducerEpochException:生产者尝试使用旧纪元进行生产。由于生产者被隔离,因此不会记录写入的偏移量,也不会发送更多记录,表明任务可能会被迁移出去

该应用程序使用 Kafka Streams 3.0.0,这是撰写本文时的最新版本。Gradle 风格的 Maven 坐标是:org.apache.kafka:kafka-streams:3.0.0

Kafka 代理在 Kubernetes 上的 Strimzi 0.23.0 下运行 Kafka 2.8.0。

我在使用 Flink 框架而不是 Kafka Streams 的类似应用程序中也遇到了完全相同的错误消息:

Flink 1.13.2:“ProducerFencedException:生产者尝试使用旧纪元进行操作”

在 Flink 和 Kafka Streams 中,仅禁用一次即可使错误消失。如果我在处理后恰好打开一次,就会发生错误。

Aiv*_*ras 2

经纪人日志中的信息是什么?就我而言,原因是:

INFO [TransactionCoordinator id=3] Completed rollback of ongoing transaction for transactionalId stats-mapper-ac83167f-5e02-4fb1-92cd-cec0e6c7332f-2 due to timeout (kafka.coordinator.transaction.TransactionCoordinator)
ERROR [ReplicaManager broker=3] Error processing append operation on partition stats.topic-1 (kafka.server.ReplicaManager)
org.apache.kafka.common.errors.InvalidProducerEpochException: Epoch of producer 1015 at offset 2395825914 in stats.topic-1 is 0, which is smaller than the last seen epoch 1
Run Code Online (Sandbox Code Playgroud)

看起来这是一项正在进行的工作KIP-588预计将在 3.2.0 KAFKA-9803中修复。

KIP 指出

这可能是由于网络分区或长时间 GC 导致客户端短时间不活动造成的。

虽然我不确定“网络分区”是什么意思 - GC 的监控和查看非常简单。