如何使用Flink流时间窗口与时间戳和水印分配器?

时间:2017-02-01 08:46:07

标签: apache-flink flink-streaming

我正在研究一种从Kafka读取事件的Flink流媒体处理器。这些事件由其中一个字段键入,并且应该在减少和输出之前在一段时间内加窗。我的处理器使用事件时间作为时间特征,因此从它消耗的事件中读取时间戳。以下是目前的情况:

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());

我对这些事件的了解如下:

  1. 他们在活动时间方面无序。
  2. 延迟到达是可能的,因此事件可能比时间戳显示的要晚得多。为了便于使用,我想我知道,最新可能的到达时间是20秒。
  3. 我希望我的活动在一分钟之前被窗口化,然后Flink将它们转发到以下的reduce操作符。
  4. 最后,这是我的问题:

    1. 鉴于我之前描述的用例,BoundedOutOfOrdernessTimestampExtractor是一个不错的选择吗?我已经阅读了我的文档,并看到了AssignerWithPunctuatedWatermarks和其他预定义的分配器可用于创建水印,但是如果那些对我来说更好的话,我们完全不了解。
    2. assignTimestampsAndWatermarks()如何与timeWindow()方法一起玩?他们可以在迟到时干涉吗?我必须记住那个区域需要记住的东西吗?

2 个答案:

答案 0 :(得分:4)

我认为我们应该从水印概念开始。简而言之,水印说大多数早期时间戳的事件已经到来。基于该假设,当水印通过窗口结束时,timeWindow可以发出窗口。当然,仍有可能发生迟到,人们可能想要处理。这里有allowedLateness的概念,它指定在发射窗口后多长时间我们应该跟踪那里的元素,以便我们可以用那些晚期事件更新我们的接收器(但必须记住窗口已经发出没有这个元素)。希望以某种方式回答你的秒问题。

回到你的第一个问题,如果有很多事件可以延迟20秒,我认为BoundedOutOfOrdernessTimestampExtractor是最好的选择。这种方式虽然发出每个窗口将延迟20秒。如果延迟抵达是相当零星的,你可以处理重复,那么你可能会考虑另一个。

您提到的AssignerWithPunctuatedWatermarks,正如文档所说,应该用于您的信息流中的某些特定事件已充当水印的情况。所以不要认为它适合你的用例。

有关水印的详细信息,您可以阅读docthisthat

答案 1 :(得分:0)

也许你的水印总是小于窗口结束时间,所以它不会触发窗口产生结果。如何触发窗口的点如下:

  1. 水印&GT; =窗结束时间
  2. 此窗口中有一些元素。