如何使用带有时间戳和水印赋值器的flink流式处理时间窗口?

rslzwgfq  于 2021-06-25  发布在  Flink
关注(0)|答案(2)|浏览(365)

我正在开发一个flink流处理器,它可以读取Kafka的事件。这些事件由其中一个字段设置关键帧,并且应该在减少和输出之前在一段时间内设置窗口。我的处理器使用事件时间作为时间特征,因此从它使用的事件中读取时间戳。以下是它目前的样子:

source
    .map(new MapEvent())
    .assignTimestampsAndWatermarks(new BoundedOutOfOrdernessTimestampExtractor<Event>(Time.seconds(10)) {
        @Override public long extractTimestamp(Event event) {
                return event.getTimestamp();
            }
        })
    .keyBy(new KeySelector())
    .timeWindow(Time.minutes(1))
    .reduce(new EventReducer())
    .map(new MapToResult());

我对这些事件的了解如下:
他们在活动时间上是无序的。
迟到是可能的,因此事件可能比时间戳所说的要晚得多。为了方便使用,假设我知道,最晚可能到达的时间是20秒。
我希望我的活动在flink将它们转发到下面的reduce操作符之前被窗口化整整一分钟。
最后,我的问题是:
考虑到我之前描述的用例 BoundedOutOfOrdernessTimestampExtractor 好的选择?我读了一遍文件,看到了 AssignerWithPunctuatedWatermarks 和其他预定义的赋值器可用于创建水印,但不完全理解,如果这些对我更好。
你觉得 assignTimestampsAndWatermarks() 和孩子们一起玩 timeWindow() 方法?他们能干涉迟到的人吗?在那个区域有什么我必须记住的东西吗?

3zwjbxry

3zwjbxry1#

可能您的水印总是小于窗口结束时间,因此它不会触发窗口以产生结果。如何触发窗口的要点如下:
水印>=窗口结束时间。
这个窗口中有一些元素。

icnyk63a

icnyk63a2#

我认为我们应该从水印的概念开始。简单地说,watermark表示大多数时间戳较早的事件已经到达。基于这个假设,当水印经过窗口的末端时,时间窗口可以发出窗口。当然,也可能会有迟到的情况,这是我们需要处理的。这个概念来了 allowedLateness 它指定在发出窗口之后,我们应该跟踪在那里的元素多长时间,以便我们可以用这些最新的事件来更新我们的接收器(但是必须记住窗口已经发出了,没有这个元素)。希望这能回答你的第二个问题。
回到你的第一个问题,如果你有很多事情可能会迟到20秒,我认为 BoundedOutOfOrdernessTimestampExtractor 是最好的选择。这样,尽管每个窗口的发射都会延迟20秒。如果延迟到达是相当零星的,你可以处理重复,然后你可以考虑另一个。
这个 AssignerWithPunctuatedWatermarks 正如doc所说,如果流中的某些特定事件已经充当水印,那么应该使用。所以不要认为它适合你的用例。
有关水印的更多信息,请阅读此文档或此和彼

相关问题