一个kafka消费者如何从无效的退休信息中恢复?

时间:2016-04-30 08:31:33

标签: apache-kafka kafka-consumer-api

我是kafka新手,当我阅读文档时,我有与卡夫卡消费者有关的设计相关问题。

  

kafka消费者从组成的kafka流中读取消息   来自一个或多个服务器的一个或多个分区。

让我们说其中一条收到的邮件已损坏,因此消费者无法处理。但是在处理事件日志时,您不希望丢弃任何事件,因此您可以进行无限次重试以避免在处理过程中出现瞬态错误。在无限重试的情况下,消费者如何向前发展。有没有办法将此消息列入黑名单以供下次重试?

我认为需要人工干预。我们在哪里记录一些消息元数据(暂时还不知道究竟是什么)来查看哪个消息失败并且在每个消费者检查redis(或其他地方?)之后都有逻辑,以便查看此消息是否需要被跳过。黑名单也不必永久存储在redis中,直到消费者可以跳过它。这是我刚刚描述的伪代码:

while (errorState) {
       if (msg in blacklist) {
           //skip
           commitOffset()
       } else {      
            errorState = processMessage(msg);       
            if (!errorState) {
                 commitOffset();
            } else {
                 // log this msg so that we can add to blacklist
                 logger.info(msg)
            }
        }
}

我想听听更有经验的人,看看有没有更好的方法来做到这一点。

1 个答案:

答案 0 :(得分:0)

我们在项目中有一个要求,即处理传入消息以更新记录取决于存在的记录。由于某些竞争条件,有时更新在插入之前到达。在这种情况下,我们实施了几种方法。

A。手动重试具有预定义的延迟。该代码检查插入是否到达。如果是这样,则处理正常进行。否则,它将休眠500ms,然后重试。这将重复10次。最后,如果仍未处理该消息,则代码将记录该消息,提交偏移量并向前移动。消息的处理始终在池中的线​​程中完成,因此也不会阻塞主线程。但是,在最坏的情况下,每条消息将花费5秒钟的申请时间。

B。最近,我们改进了上述解决方案,以使用基于kafka的消息调度程序。因此,现在,如果insert在更新之前尚未到达,系统会将其发送到在kafka上运行的单独的调度程序。此调度程序将在一段时间后重播该消息。重试3次后,我们将再次记录该消息,并停止计划或重试。这给我们带来的好处是,不阻塞应用程序线程,并在我们希望再次重播消息时进行管理。