我正在编写一个KafkaStreams(v2.1.0)应用程序,该应用程序从常规的Kafka主题读取消息,将这些消息与压缩的changelog主题的元数据左连接,并使用处理器运行结果对状态进行一些状态处理根据事件时间按固定的时间间隔进行打标。数据主题中的消息具有时间戳,并定义了自定义TimestampExtractor(它定义了事件时间,如我想在puctuate调用中使用的那样)。但是,元数据主题中的消息没有时间戳,但是KafkaStreams似乎无论如何都需要定义TimestampExtractor。现在,如果我在Kafka消息ExtractRecordMetadataTimestamp
中使用嵌入式元数据,或者只是在WallclockTimestampExtractor
中使用它,都会破坏应用程序的逻辑,因为元数据主题的这些时间戳似乎也会触发处理器中的标点调用,但是我的数据主题中的事件时间可以比挂钟时间晚几个小时,而我只想在这些事件上使用标点调用触发。
我的问题是如何避免从此压缩的元数据主题中提取的时间戳触发标点调用?
乍一看似乎有用的一个技巧是始终将0作为这些元数据消息的时间戳记,但是我不确定它不会有不需要的副作用。另一个解决方法是不要完全依靠“标点”来实现对事件时间的自己跟踪,但是我更喜欢使用标准的KafkaStreams方法。那么也许还有另一种方法可以解决这个问题?
这是我的应用程序的结构:
KStream<String, Data> input =
streamsBuilder.stream(dataTopic,
Consumed.with(Serdes.String(),
new DataSerde(),
new DataTimestampExtractor(),
Topology.AutoOffsetReset.LATEST));
KTable<String, Metadata> metadataTable =
streamsBuilder.table(metadataTopic,
Consumed.with(Serdes.String(),
new MetadataSerde(),
new WhichTimestampExtractorToUse(),
Topology.AutoOffsetReset.EARLIEST));
input.leftJoin(metadataTable, this::joiner)
.process(new ProcessorUsingPunctuateOnEventTime());