java - 避免apache kafka使用者中重复消息的有效策略

我已经学了阿帕奇卡夫卡一个月了。然而,我现在陷入了困境。我的用例是,我在不同的机器上运行两个或多个消费者进程。我做了一些测试,在Kafka服务器上发布了10000条消息。然后在处理这些消息时,我杀死了一个使用者进程并重新启动了它。消费者正在将处理过的消息写入文件中。因此,在消耗完成后,文件显示了超过10000条消息。所以有些信息是重复的。
在使用者进程中,我禁用了自动提交。使用者手动批量提交补偿。因此,例如,如果将100条消息写入文件,则使用者提交偏移量。当单个使用者进程正在运行并且崩溃和恢复时,可以通过这种方式避免重复。但是,当多个使用者正在运行,其中一个崩溃并恢复时,它会将重复的消息写入文件。
有没有有效的策略来避免这些重复的信息?


最佳答案:

简短的回答是,不。
你要找的只是一次处理。虽然这似乎常常是可行的,但不应该依赖于它,因为总有警告。
即使为了防止重复,您也需要使用简单的使用者。这种方法对每个使用者的工作方式是:当从某个分区消费消息时,将消费消息的分区和偏移量写入磁盘。当使用者在失败后重新启动时,从磁盘读取每个分区的上次使用的偏移量。
但即使有了这种模式,消费者也不能保证在失败后不会重新处理消息。如果使用者使用了一条消息,然后在将偏移量刷新到磁盘之前失败,该怎么办?如果在处理消息之前写入磁盘,那么如果在实际处理消息之前写入偏移量,然后失败呢?即使在每次发送消息后都向动物园管理员提交补偿,也会存在同样的问题。
不过,有些情况下
仅仅一次处理更容易实现,但只适用于某些用例。这只需要将偏移量存储在与单元应用程序输出相同的位置。例如,如果编写一个对消息进行计数的使用者,通过将上次计数的偏移量与每个计数一起存储,可以确保偏移量与使用者的状态同时存储。当然,为了保证只处理一次,这就要求您只使用一条消息,并为每条消息更新一次状态,这对于大多数Kafka消费应用程序来说完全不现实。从本质上讲,出于性能原因,卡夫卡成批地使用消息。
通常情况下,如果简单地将应用程序设计为等量的,那么您的时间将被更好地利用,并且您的应用程序将更加可靠。