KafkaProducer sendOffsetsToTransaction需要偏移+ 1才能成功提交当前偏移量

时间:2017-09-13 16:35:17

标签: scala apache-kafka kafka-producer-api apache-kafka-streams

我试图在Kafka Processor中实现交易,以确保我不会再次处理同一条消息。给定消息(A)我需要创建将在事务中的另一个主题上生成的消息列表,并且我想在同一事务中提交原始消息(A)。从文档中我发现了Producer方法sendOffsetsToTransaction,它似乎只有在成功时才能在事务中提交偏移量。这是我process()的{​​{1}}方法中的代码:

Processor

不幸的是,这个代码(每次执行时显然都失败了)每次在异常后重新启动应用程序时,都会重新处理已处理的消息(A)。

我设法让它在 producer.beginTransaction() val topicPartition = new TopicPartition(this.context().topic(), this.context().partition()) val offsetAndMetadata = new OffsetAndMetadata(this.context().offset()) val map = Map(topicPartition -> offsetAndMetadata).asJava producer.sendOffsetsToTransaction(map, "consumer-group-id") items.foreach(x => producer.send(new ProducerRecord("items_topic", x.key, x.value))) producer.commitTransaction() throw new RuntimeException("expected exception") 返回的偏移量中添加+1并以这种方式重新定义this.context().offset()

val offsetAndMetadata

这是正常行为还是我做错了什么?

谢谢:)

2 个答案:

答案 0 :(得分:2)

您的代码是正确的。

您提交的偏移量是您要下次读取的消息的偏移量(而不是您上次读取的消息的偏移量)。

比较:https://github.com/apache/kafka/blob/41e4e93b5ae8a7d221fce1733e050cb98ac9713c/streams/src/main/java/org/apache/kafka/streams/processor/internals/StreamTask.java#L346

答案 1 :(得分:0)

您可以使用而不是向偏移量加1

<embed>

这将返回将给出的下一个记录的偏移量。这将比消费者在该分区中看到的最高偏移量大一个