kafka - 如何以容错方式读取和处理消息?

kafka - How to read and process messages in a fault tolerant way?

我是 Kafka 的新手,我正在尝试了解 Kafka 消费者如何使用和处理来自 Kafka 主题的消息如果消费者在这期间失败而不会丢失消息.

例如:

有一个名为 cart_checkout 的 kafka 主题,它只在用户成功结账时保存一个事件。它所要做的就是获得一个事件并向用户发送一封电子邮件,告知他们的项目已签出。

这是幸福的道路:

  1. 消费者从主题中获取一个事件。
  2. 读取偏移量已提交给 Kafka。
  3. 消费者调用应用特定功能来发送电子邮件。
  4. 重复。

如果应用程序在 Step 3 期间失败会怎样?

如果消费者启动,那么它会错过一个事件,对吗? (因为阅读的消息已提交)

消费者可以倒带但它怎么知道要倒带?

RabbitMQ解决方案:

在 RabbitMQ 中似乎更容易解决,因为我们可以控制消息的 ACK。但是在 Kafka 中,如果我们提交读取偏移量,我们会在应用程序重新启动时丢失消息,如果我们不提交读取偏移量,那么相同的消息将发送给多个消费者

处理这个问题的最佳方法是什么?

正如您提到的,消费者抵消也可以手动管理,在这种情况下您需要手动管理,以避免重复(默认情况下,交付保证至少一次)或丢失您的用例中提到的电子邮件。

手动控制偏移量 auto-commit 应该被禁用 (enable.auto.commit = false)。

现在关于你提到的问题的第二部分:

if we don't commit the read-offset then the same message is sent to multiple consumers

这个理解并不完全正确。在 Kafka 中,默认情况下每个消费者控制自己的偏移量,并且 同一消费者组 中的消费者不共享分区(同一消费者组中的每个消费者都从单个分区读取)因此消息将不会被同一消费者组中的其他消费者处理(在 Kafka 消费者轮询消息中),这只会发生在不同消费者组中的消费者,但无论如何他们也会阅读消息,这是 Kafka 的设计客户。同样重要的是,您了解消费者轮询 returns 多条消息和默认的 commitSync 或 commitAsync 将提交该轮询调用返回的所有消息的偏移量,如果您想避免可能的电子邮件重复,您可能想要使用更多具体提交,检查API这里:https://kafka.apache.org/30/javadoc/index.html?org/apache/kafka/clients/consumer/KafkaConsumer.html

当你了解到这是一个常见的误解时,有一些很好的资源可供阅读,可以免费澄清这个概念,我建议文档的官方设计部分:https://kafka.apache.org/documentation/#theconsumer also this free book chapter: https://www.oreilly.com/library/view/kafka-the-definitive/9781491936153/ch04.html 具体到什么你现在正在做。祝你好运。