【问题标题】:Can Kafka consumer group running on different machines receive unique messages?运行在不同机器上的 Kafka 消费者组可以接收到唯一的消息吗?
【发布时间】:2015-06-13 09:17:37
【问题描述】:

为避免消费者崩溃并重新启动时出现多余的消息,我禁用了偏移量的自动提交并手动提交它们。

现在的问题是,如果不同机器上的消费者进程访问相同的主题,它们会收到唯一的消息吗?从理论上看,手动提交会导致在不同机器上收到冗余消息。

在我的本地机器上,我运行了两个订阅同一主题的 Java 消费者实例,它们收到了重复的消息。如何解决这件事?我正在使用高级消费者

【问题讨论】:

    标签: java message-queue apache-kafka


    【解决方案1】:

    由于 Kafka 的消息传递语义是at-least-once,因此您应该实现自己的代码来保证 Kafka 中的exactly-once语义。

    • 最多一次:消息可能会丢失,但永远不会重新传递。
    • 至少一次:消息永远不会丢失,但可以重新传递。
    • 恰好一次:这是人们真正想要的,每条消息只传递一次。

    来自 Kafka 文档中的 4.6 Message Delivery Semantics

    那么恰好一次语义(即你真正想要的东西)呢?这里的限制实际上并不是消息系统的一个特性,而是需要将消费者的位置与实际存储为输出的内容协调起来。实现这一点的经典方法是在消费者位置的存储和消费者输出的存储之间引入两阶段提交。但这可以通过简单地让消费者将其偏移量存储在与其输出相同的位置来更简单和更普遍地处理。这更好,因为消费者可能想要写入的许多输出系统不支持两阶段提交。例如,我们在 HDFS 中填充数据的 Hadoop ETL 将其偏移量与它读取的数据一起存储在 HDFS 中,从而保证数据和偏移量都被更新或两者都不更新。对于许多其他需要这些更强语义并且消息没有主键以允许重复数据删除的数据系统,我们遵循类似的模式。

    Kafka FAQ 中也有一个类似回答的问题:How do I get exactly-once messaging from Kafka?

    【讨论】:

    • 感谢您的回答。现在的实际情况是失败的情况。消费者手动提交偏移量。因此,当消费者提交偏移量时,它是针对整个主题还是它自己的偏移量提交?如果一个消费者处理完一条消息并提交了偏移量,而另一个消费者仍在处理另一条消息并失败了,那么当该消费者恢复时,它会丢失那条未处理的消息吗?
    • 例如 c1 => message @ offset 2 和 c2 => message @ offset 1。c1 完成处理他的消息并提交偏移量。那时 c2 仍在处理他的偏移量 1 的消息,并且在发生崩溃之前。现在直到那时 c1 已经移动并正在处理消息@偏移量 3。c2 现在出现了。那么它将收到哪个偏移量的消息?
    • @Shades88 你给我的场景不可能发生。每个分区都有自己的偏移量,每个分区都分配给一个消费者。每个分区只能由分配给它的消费者访问。也就是说,两个消费者不能访问同一个分区,也不能访问同一个偏移序列。有关信息,请参阅我的其他答案:stackoverflow.com/a/29314029/961314stackoverflow.com/a/29291884/961314
    • 好吧,我的基础还不清楚。 Bt 现在另一个问题。如果消费者只分配了一个特定的分区。而且我只有一个消费者,那么其余的分区怎么用呢?我的意思是,到目前为止,我已经测试了单个消费者订阅具有 3 个分区的主题。消费者似乎正在从所有分区中读取数据
    • @Shades88 一个partition被分配给一个consumer,但是一个consumer可以负责多个partition。它们之间的关系不是一对一的、消费者对分区的。它是一对多,消费者对分区。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-05
    • 1970-01-01
    • 1970-01-01
    • 2020-04-19
    • 2022-01-06
    • 1970-01-01
    相关资源
    最近更新 更多