Java 在不同机器上运行的卡夫卡消费群体能否收到唯一的消息?

Java 在不同机器上运行的卡夫卡消费群体能否收到唯一的消息?,java,message-queue,apache-kafka,Java,Message Queue,Apache Kafka,为了避免消费者崩溃和恢复时出现冗余消息,我禁用了偏移量的自动提交和手动提交 现在的问题是,如果消费者进程在不同的机器上访问同一主题,它们会收到唯一的消息吗?从理论上看,手动提交将导致在不同的机器上接收到冗余消息 在我的本地机器上,我运行了两个java消费者订阅同一主题的实例,它们得到了重复的消息。如何解决这个问题?我使用的是高级消费者,因为Kafka的消息传递语义至少有一次,所以您应该实现自己的代码,以保证Kafka中的语义只有一次 最多一次:消息可能会丢失,但永远不会重新发送 至少一次:邮件

为了避免消费者崩溃和恢复时出现冗余消息,我禁用了偏移量的自动提交和手动提交

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


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

,因为Kafka的消息传递语义至少有一次,所以您应该实现自己的代码,以保证Kafka中的语义只有一次

  • 最多一次:消息可能会丢失,但永远不会重新发送
  • 至少一次:邮件不会丢失,但可以重新发送
  • 只有一次:这是人们真正想要的,每条信息只传递一次
卡夫卡文献中的:

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


卡夫卡常见问题解答中还有一个问题有类似的答案:

谢谢你的回答。现在实际情况是失败。消费者正在手动提交补偿。所以,当消费者提交偏移量时,它是为整个主题提交偏移量,还是为它自己的偏移量?。如果一个使用者已完成处理一条消息并提交偏移量,而另一个使用者仍在处理另一条消息并失败,则当该使用者返回时,它是否会丢失该未处理的消息?例如c1=>message@offset 2和c2=>message@offset 1。c1完成对其消息的处理并提交偏移量。此时c2仍在处理其偏移量1的消息,并在提交崩溃之前。现在,直到那个时候,c1已经移动并正在处理偏移量3处的消息。c2现在出现了。那么它将收到哪个偏移量的消息?@Shades88您给我的场景不会发生。每个分区都有自己的偏移量,每个分区都分配给一个使用者。每个分区只能由分配给它的使用者访问。也就是说,两个使用者不能访问相同的分区或相同的偏移序列。有关信息,请参考我的其他答案:好的,我的基本知识不清楚。现在是另一个问题。如果仅为使用者分配了特定分区。我只有一个消费者,那个么为什么要使用其余的分区呢?我的意思是,到目前为止,我已经测试了单个消费者订阅一个有3个分区的主题。而消费者似乎正在从所有人身上阅读partitions@Shades88分区分配给单个使用者,但单个使用者可以负责多个分区。它们之间的关系不是一对一、消费者对分割。它是一对多,消费者对分区。