我使用org.apache.kafka:kafka-streams:0.10.0.1
我正在尝试使用基于时间序列的流,它似乎不会触发KStream.Process()
触发(“标点符号”)。 (参见here)
在KafkaStreams
配置中,我传递了这个参数(等等):
config.put(
StreamsConfig.TIMESTAMP_EXTRACTOR_CLASS_CONFIG,
EventTimeExtractor.class.getName());
这里,EventTimeExtractor
是一个自定义时间戳提取器(实现org.apache.kafka.streams.processor.TimestampExtractor
),用于从JSON数据中提取时间戳信息。
我希望这可以在每个新记录被拉入时调用我的对象(从TimestampExtractor
派生)。所讨论的流是2 * 10 ^ 6条记录/分钟。我punctuate()
设置为60秒,它永远不会触发。我知道数据非常频繁地传递了这个范围,因为它将旧值拉回来。
事实上它永远不会被召唤。
答案 0 :(得分:8)
2017年11月更新:Kafka 1.0中的Kafka Streams现在支持punctuate()
同时具有流时间和处理时间(挂钟时间)行为。所以你可以选择自己喜欢的行为。
您的设置对我来说似乎是正确的。
您需要注意的事项:从Kafka 0.10.0开始,punctuate()
方法在 stream-time 上运行(默认情况下,即基于默认时间戳提取器,流 - 时间将意味着事件时间)。并且只有在新数据记录进入时才会提前流时间,并且流时间的提前量由这些新记录的相关时间戳决定。
例如:
punctuate()
设置为每1分钟调用一次= 60 * 1000
(注意:流时间 1分钟)。现在,如果在接下来的5分钟内没有收到任何数据,则根本不会调用punctuate()
- 即使您可能希望它被调用5次。为什么?同样,因为punctuate()
取决于流时间,并且流时间仅基于新接收的数据记录而提前。这可能导致你看到的行为吗?
展望未来:Kafka项目中已经开始讨论如何使punctuate()
更加灵活,例如触发它不仅基于stream-time
(默认为event-time
),而且基于processing-time
。
答案 1 :(得分:2)
您的方法似乎是正确的。比较http://docs.confluent.io/3.0.1/streams/developer-guide.html#optional-configuration-parameters
中的pargraph “Timestamp Extractor(timestamp.extractor):”不确定,为什么不使用自定义时间戳提取器。看看org.apache.kafka.streams.processor.internals.StreamTask
。在构造函数中应该有类似
TimestampExtractor timestampExtractor1 = (TimestampExtractor)config.getConfiguredInstance("timestamp.extractor", TimestampExtractor.class);
检查您的自定义提取器是否被拾取......
答案 2 :(得分:1)
我认为这是经纪人层面的另一个问题。我使用具有更多CPU和RAM的实例重建了集群。现在我得到了我预期的结果。
远程观察者注意:如果您的 KStream 应用程序行为奇怪,请查看您的经纪人并确保他们不会卡在GC中并且有足够的“净空”文件句柄,RAM等。