我在一些关于堆栈溢出的答案中看到,并且在网络中一般都认为Kafka不支持消费承认的想法,或者恰好一次消费很难实现。
在以下条目中作为样本 Is there any reason to use RabbitMQ over Kafka?,我可以阅读以下声明:
RabbitMQ将保留关于消费/已确认/未确认消息的所有状态,而Kafka不会
或
恰好一旦Kafka很难获得保证。
通过阅读官方Kafka文档,我不明白这一点: https://kafka.apache.org/documentation/#design_consumerposition
之前的文档指出Kafka不使用传统的确认实现(如RabbitMQ)。相反,他们依赖于关系分区 - 消费者和偏移......
这相当于消息确认非常便宜
有人可以解释为什么"只有一次消费保证"在卡夫卡很难实现?和Kafka与其他更传统的Message Broker作为RabbitMQ有何不同?我错过了什么?
答案 0 :(得分:10)
如果你的意思是一旦问题是这样的话。 您可能知道Kafka消费者使用轮询机制,即消费者向服务器询问消息。此外,您需要回忆消费者提交消息偏移量,也就是说,它告诉群集下一个预期偏移量是什么。所以,想象一下会发生什么。
对消息进行消费者调查并获取offset = 1的消息。
A)如果消费者提交在处理消息之前立即偏移,那么它可能会崩溃并且永远不会再次接收该消息,因为它已经提交,在下次轮询时Kafka将返回offset = 2的消息。这就是他们所说的最多一次是语义。
B)如果消费者首先处理消息然后提交偏移量,那么可能发生的是,在处理消息之后但在提交之前,消费者崩溃,因此在这种情况下,下次轮询将再次获得具有offset = 1的相同消息并且该消息将被处理两次。这就是他们至少称之为一次。
为了实现一次,您需要处理消息并在原子操作中提交该偏移量,在该操作中,您始终同时执行这两个操作,或者不执行任何操作。这不是那么容易的。执行此操作的一种方法(如果可能)是存储处理结果以及生成该结果的消息的偏移量。然后,当消费者开始时,它会在Kafka之外寻找最后一个处理过的偏移量并寻找该偏移量。