Java kafka流跳跃窗口聚合导致时间戳为零的多个窗口

Java kafka流跳跃窗口聚合导致时间戳为零的多个窗口,java,kafka-consumer-api,apache-kafka-streams,spring-kafka,spring-cloud-stream,Java,Kafka Consumer Api,Apache Kafka Streams,Spring Kafka,Spring Cloud Stream,Kafka流DSL窗口聚合导致多个窗口 @StreamListener("input") public void process(KStream<String, Data> DataKStream) { JsonSerde<DataAggregator> DataJsonSerde = new JsonSerde<>(DataAggregator.class); DataKStream

Kafka流DSL窗口聚合导致多个窗口

@StreamListener("input")
    public void process(KStream<String, Data> DataKStream) {

        JsonSerde<DataAggregator> DataJsonSerde =
                new JsonSerde<>(DataAggregator.class);

        DataKStream
                .groupByKey()
                .windowedBy(TimeWindows.of(60000).advanceBy(30000))
                .aggregate(
                        DataAggregator::new,
                        (key, Data, aggregator) -> aggregator.add(Data),
                        Materialized.with(Serdes.String(), DataJsonSerde)
                );
    }
实际输出:

[1]
[1, 2]
[1, 2, 3]
[1, 2, 3, 4]
[1, 2, 3, 4, 5]
[1, 2, 3, 4, 5, 6] // till 30 seconds only one window
[6] // new window after 30 seconds
[1, 2, 3, 4, 5, 6, 7]
[6, 7]
[1, 2, 3, 4, 5, 6, 7, 8]
[6, 7, 8]
[1]
[1]
[1, 2]
[1, 2]
[1, 2, 3]
[1, 2, 3]
[1, 2, 3, 4]
[1, 2, 3, 4]
[1, 2, 3, 4, 5]
[1, 2, 3, 4, 5]
[1, 2, 3, 4, 5, 6]
[1, 2, 3, 4, 5, 6] // duplicate window even before 30 seconds
[6] // new window after 30 seconds and 1 window from earlier will be dropped
[1, 2, 3, 4, 5, 6, 7]
[6, 7]
因为我在一分钟内创造了30秒的希望窗口。我认为,最初应该只有一个窗口,30秒后应该创建另一个窗口

有人能告诉我,实际输出是预期行为还是我遗漏了什么

注意:我每4秒获取一次输入数据,预期/实际输出仅用于表示

来自卡夫卡文档:

[1]
[1, 2]
[1, 2, 3]
[1, 2, 3, 4]
[1, 2, 3, 4, 5]
[1, 2, 3, 4, 5, 6] // till 30 seconds only one window
[6] // new window after 30 seconds
[1, 2, 3, 4, 5, 6, 7]
[6, 7]
[1, 2, 3, 4, 5, 6, 7, 8]
[6, 7, 8]
[1]
[1]
[1, 2]
[1, 2]
[1, 2, 3]
[1, 2, 3]
[1, 2, 3, 4]
[1, 2, 3, 4]
[1, 2, 3, 4, 5]
[1, 2, 3, 4, 5]
[1, 2, 3, 4, 5, 6]
[1, 2, 3, 4, 5, 6] // duplicate window even before 30 seconds
[6] // new window after 30 seconds and 1 window from earlier will be dropped
[1, 2, 3, 4, 5, 6, 7]
[6, 7]
跳跃时间窗口与历元对齐,间隔较短 边界是包含的,上限是独占的。“符合 “历元”表示第一个窗口从时间戳0开始。对于 例如,跳转窗口大小为5000ms,前进间隔为 3000毫秒的(“跃点”)具有可预测的窗口边界 [0;5000],[3000;8000],…-而不是[1000;6000],[4000;9000],…甚至 像[1452;6452]、[4452;9452]、


由于窗口重叠,每个时间戳有多个窗口。对于特定的窗口配置,始终有两个窗口(以毫秒为单位):

您无法更改此行为,但是,您可以对结果应用
filter()
(即,
aggregate(…)。filter(…)
以删除您不感兴趣的窗口


此外,默认情况下,记录事件时间由Kafka Streams使用。有一个
WallclockTimestampExtractor
,但只有在显式设置时才使用它。Cf.

我相信这是来自Kafka Streams的默认行为。它使用一个wall clock TimestampExtractor,窗口是基于wallclock时间f生成的根据我的理解,在你的情况下,启动应用程序时会创建两个窗口,比如-
“开始”:[2019,11,20,17,39,30],“结束”:[2019,11,20,17,40,30]
“开始”:[2019,11,20,17,40],“结束”:[2019,11,20,17,41]
。因此,两个窗口都会选择键。但是核心卡夫卡流团队的人可能想确认这一点。@sobychacko感谢您的回复。有没有办法避免这种情况?我一开始不需要两个窗口。是否可以使用消息时间戳而不是挂钟时间戳进行窗口设置?@PratapA.K,sobychacko的帖子听起来很合理。跳跃窗口与历元对齐(请参阅)。如果需要不同的行为,可以使用
transform()实现自定义窗口
@brunocadona我不希望有不同的行为。根据卡夫卡文档,时间戳为零时应创建一个窗口,但在我的情况下,时间戳处有两个窗口zero@PratapA.K您确定从您的第一条记录中提取的时间戳为零,即1970年1月1日吗?谢谢您的回复。因此,总结一下,如果我有5分钟的风1分钟跳跃后,开始时将有5个窗口。这是否正确?这取决于你所说的“开始时”是什么意思。如果“开始”为0,则表示否,因为这是一种极端情况。如果“开始”是2019年的某个时间戳,则表示是。