立即更新Kafka偏移

时间:2018-10-17 07:59:18

标签: java spring spring-boot apache-kafka spring-kafka

我正在开发一个Spring Boot应用程序,该应用程序对推送到Kafka队列中的消息做出反应。

版本是Spring Boot 2.0.5,Finchley.SR1。

Kafka版本为kafka_2.12-1.1.0

我面临的问题是有时,当我重新启动应用程序时,它会重放旧消息。这种情况并不总是会发生-我发现的唯一模式是,它似乎是在几天不活动之后(例如星期一早上,周末之后)。

作为开发的一部分,我在一天中多次停止并启动该应用程序,只是偶尔会看到相同的问题。它也不与应用程序中的错误链接,因为所有处理都是干净的。

我已将我的Kafka侦听器配置为使用MANUAL_IMMEDIATE确认,并在侦听器方法的末尾调用ack.acknowledge()。

我的Spring属性文件如下所示:

spring:
  kafka:
    bootstrap-servers: kafka:9092
    listener:
      ack-mode: MANUAL_IMMEDIATE
    consumer:
      enable-auto-commit: false
      auto-offset-reset: earliest
      group-id: user-mgmt-app

我的侦听器类的定义如下:

@org.springframework.kafka.annotation.KafkaListener(topics = "aggregate-event-topic")
public void receive(ConsumerRecord<?, ?> cr, Acknowledgment ack) {

   ...
   ack.acknowledge();

}

我有一个正在运行的应用程序实例,因此每次都是消费者组的负责人。

我使用了Kafka工具来查看消费者组的偏移量,我注意到的一件事是,当我在确认步骤中断点应用程序时,它并没有更新CURRENT-OFFSET,而只是更新了处理完所有邮件后,便会自动保存。

./kafka-consumer-groups.sh --bootstrap-server kafka:9092 --group user-mgmt-app --describe

从其他帖子中我了解到,MANUAL_IMMEDIATE将在调用acknowedge()之后而不是在批处理结束时立即更新Kafka服务器。

我的理解不正确吗?如果有的话,无论如何都能获得我想要的功能(例如,将分区的每次读取的批处理大小设置为1,我猜这可能会对性能产生影响)。如果是这样,我该怎么做(非常感谢您接受任何帮助!)

TIA

1 个答案:

答案 0 :(得分:0)

  

我面临的问题是,有时,当我重新启动应用程序时,它会重播旧消息。这种情况并非总是会发生-我发现的唯一模式是,它似乎是在几天不活动之后(例如星期一早上,周末之后)。

我猜您不是在使用2.0.0经纪人,其中,消费者抵销的默认保留时间从24小时增加到7天。较早的经纪人仅在一天后就使补偿期满-如果您周末没有消息,这是一个经典问题。

请参见Notable Changes in 2.0.0

  

KIP-186将默认偏移保留时间从1天增加到7天。这使得它不太可能在丢失的应用程序中“丢失”偏移量。它还会增加活动的偏移量集,因此会增加代理上的内存使用量。请注意,控制台使用者当前默认情况下启用偏移提交,并且可以是大量偏移的来源,此更改现在将保留7天而不是1天。您可以通过设置代理配置offsets.retention来保留现有行为。分钟到1440。

我不确定为什么您没有通过命令行工具看到偏移量更新。 AckMode.RECORD将在每条记录后更新偏移量。只要Spring Kafka版本> = 1.3(启动2.0.x将拉入Spring Kafka 2.0.x),MANUAL_IMMEDIATE就会在您调用acknowledge()时更新。