繁体   English   中英

Kafka KStream-KStream leftjoin 使用自定义 TimestampExtractor 窗口化导致过期段的跳过记录

[英]Kafka KStream-KStream leftjoin windowed with custom TimestampExtractor cause Skipping record for expired segment

我正在尝试使用自定义 TimestampExtractor 加入 2 KStream (stream1, stream2),如果我的 2 个事件的时间戳彼此接近,我得到:

[my-app-client-StreamThread-1] WARN org.apache.kafka.streams.state.internals.AbstractRocksDBSegmentedBytesStore - Skipping record for expired segment.

为了测试,我尝试不使用自定义TimestampExtractor ,如果我的生产者足够快地发送事件并尊重我的窗口持续时间配置,它就可以工作。

有任何想法吗 ?

我已经查看了文档,但在加入 2 KStreams 时没有看到有关自定义 TimestampExtractor 的限制?

以下是有关该问题的更多详细信息:

我的 TimestampExtractor 从事件负载中提取时间戳:

public class EventTimestampExtractor implements TimestampExtractor {
    @Override
    public long extract(final ConsumerRecord<Object, Object> record, final long previousTimestamp) {
        final Event event = (Event) record.value();
        final long timestamp = = event.myTimestamp;
        return timestamp;
    }
}

这是我的应用程序:

    final Properties props = new Properties();
    props.put(StreamsConfig.DEFAULT_TIMESTAMP_EXTRACTOR_CLASS_CONFIG, EventTimestampExtractor.class);
    
    ...
    
    final StreamsBuilder builder = new StreamsBuilder();


    final KStream<String, Event> stream1 =
            builder.stream("topic-left", Consumed.with(Serdes.String(),
                    EventSerde.serde()));

    final KStream<String, Event>  stream2 =
            builder.stream("topic-right", Consumed.with(Serdes.String(),
                    EventSerde.serde()));


    stream1.leftJoin(stream2,
            (eventLeft, eventRight) -> {

                ... processing ...
                
                Data data = merge(eventLeft.data, eventRight.data);
                
                return data;

            },
            JoinWindows.of(Duration.ofMillis(1000)).grace(Duration.ofMillis(60000)),
            StreamJoined.with(Serdes.String(), EventSerde.serde(), EventSerde.serde())
    )
    .peek((key, data) -> {
        LOG.debug(key + data);
    });

    ...
    
    final KafkaStreams streams = new KafkaStreams(builder.build(), props);
    streams.start();
    

在那之后,我用注入卡夫卡控制台制片人控制台, eventLeft"topic-left"eventRight"topic-right" ,其中:

  • eventLeft.myTimestamp = T (in ms)
  • eventRight.myTimestamp = T+200 (in ms)

我的问题是,我没有登录peek() ,而是得到了:

[my-app-client-StreamThread-1] WARN org.apache.kafka.streams.state.internals.AbstractRocksDBSegmentedBytesStore - Skipping record for expired segment.

当我在EventTimestampExtractor显示时间戳值时,一切似乎都正常。

问题似乎重复这个一个

我没有使用kafka-console-producer控制台和硬编码时间戳,而是使用一个应用程序,它可以在没有硬编码时间戳的情况下生成我的数据,并且它可以工作。

我不明白为什么它不能与kafka-console-producer控制台一起使用,在记录内部和提取的时间戳周围一定有一些棘手的行为。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM