4

这可能是使用 kafka-node -negative timestamp 的 Kafka Streams 中的 Error的重复,但肯定不是。我的 Kafka Streams 应用程序对每条消息执行一些转换逻辑并将其转发到新主题。应用程序中没有基于时间的聚合/处理,因此不需要使用任何自定义时间戳提取器。这个应用程序运行了好几天,但突然之间应用程序抛出了一个负时间戳异常。

Exception in thread "StreamThread-4" org.apache.kafka.streams.errors.StreamsException: Extracted timestamp value is negative, which is not allowed.

从所有 StreamThreads(总共 10 个)抛出此异常后,该应用程序有点冻结,因为几个小时内流没有进一步的进展。之后没有抛出异常。当我重新启动应用程序时,它开始只处理新来的消息。

现在的问题是,介于两者之间的那些消息发生了什么(在引发异常之后和重新启动应用程序之前)。万一,那些丢失的消息没有嵌入时间戳(极不可能,因为代理和生产者没有发生任何变化),是不是应用程序应该为每条这样的消息抛出异常?或者是不是像应用程序在第一次检测到消息中的负时间戳时停止流进度?有没有办法处理这种情况,以便应用程序可以处理流,即使在检测到任何负时间戳之后?我的应用程序使用 Kafka Streams 库版本 0.10.0.1-cp1。

注意:我可以轻松地建立一个自定义时间戳提取器,它可以检查每条消息中的负时间戳,但这对我的应用程序来说是很多不必要的开销。我只想了解为什么在检测到带有负时间戳的消息后流没有进行。

4

1 回答 1

5

即使您没有任何基于时间的运算符,Kafka Streams 应用程序也会检查从时间戳提取器返回的时间戳是否有效,因为时间戳用于确定来自不同分区的记录的处理顺序,以确保记录按顺序处理并且所有分区以基于时间的对齐方式消耗。

如果检测到负时间戳,则应用程序(或实际上是相应的线程)终止。不幸的是,目前无法从此类异常中恢复,您需要重新启动应用程序。另请参阅 Confluent 常见问题解答:http ://docs.confluent.io/3.1.1/streams/faq.html#invalid-timestamp-exception

如果您的应用程序死了并且您重新启动它,它将从中断的地方继续处理。不幸的是,在 Kafka0.10.0.1中存在一个错误(在即将发布的版本中修复0.10.2),如果失败,可能会提交不正确的偏移量,并且应用程序会“跳过”一些记录。我假设这发生在您的情况下,并且如果您只有一些时间戳无效的记录,则这些记录可能已被跳过,从而允许您的应用程序在重新启动后恢复。这种行为实际上是一个错误——如果没有错误,Kafka Stream 将尝试一次又一次地处理那些时间戳无效的记录,并且每次都失败,直到您提供一个自定义时间戳提取器,该提取器通过返回一个有效的时间戳来解决问题。

如何修复它:

正确的解决方法是提供一个从不返回无效(即负)时间戳的自定义时间戳提取器。

我无法解释为什么您的时间戳无效......这很奇怪,您可能想调查您的生产者设置并尝试确定您的生产者是否有可能放置无效时间戳(即使这不太可能 - - 我不知道问题的根本原因是什么)。

补充说明:

在下一个版本0.10.2(例如,这允许您自动跳过具有无效时间戳的记录,而不是引发错误(当前行为)。有关更多详细信息,请参阅 KIP-93:https ://cwiki.apache.org/confluence/display/KAFKA/KIP-93%3A+Improve+invalid+timestamp+handling+in+Kafka+Streams

于 2016-12-27T13:11:01.593 回答