即使在Kafka Streams中无法发布到输出主题时,是否也会使用消费者补偿?

时间:2019-05-31 06:54:57

标签: apache-kafka apache-kafka-streams

如果我有一个Kafka流应用程序无法发布到某个主题(因为该主题不存在),它会提交使用者偏移并继续,还是会在同一条消息上循环直到它可以解决输出主题?根据我的观察,该应用程序仅会打印错误并可以正常运行。

尝试发布到主题时的错误示例:

Error while fetching metadata with correlation id 80 : {super.cool.test.topic=UNKNOWN_TOPIC_OR_PARTITION}

在我看来,它只是处理同一条消息,直到问题解决为止,以便不丢失数据?对于默认行为,我找不到明确的答案。我们尚未将autocommit设置为off或类似的设置,大多数设置都设置为默认设置。

我之所以问是因为我们不想在健康检查很好的情况下结束(应用程序正在运行,同时打印错误以记录日志),而我们只是丢弃了大量的Kafka消息。

1 个答案:

答案 0 :(得分:2)

在这种情况下,Kafka Streams不会提交偏移量,因为它提供了至少一次的处理保证(实际上,甚至不可能以不同的方式重新配置Kafka Streams-只有更严格的一次保证是可能的)。另外,由于Kafka Streams自行管理提交偏移,因此Kafka Streams始终在使用者上禁用自动提交(并且不允许您启用它)。

如果使用默认设置运行,则生产者实际上应该引发异常,并且相应的线程应该死亡-如果线程死亡,则可以通过注册KafkaStreams#uncaughtExceptionHandler()来获得回调。

您还可以观察KafkaStreams#state()(或注册一个回调KafkaStreams#setStateListener())。如果所有线程均已失效,则状态将进入DEAD(请注意,在此情况下,https://issues.apache.org/jira/browse/KAFKA-5372的旧版本中存在一个错误,其状态仍为RUNNING

因此,应用程序不应处于正常状态,Kafka Streams不会重试输入消息,但会停止处理,因此您需要重新启动客户端。重新启动后,它将重新读取失败的输入消息,然后重试以写入输出主题。

如果要重试Kafka Streams,则需要增加生产者配置reties,以避免生产者抛出异常并重试内部写入。如果生产者写缓冲区变满,最终可能会“阻止”进一步的处理。