应用windowedFunction后窗口中没有内容

时间:2017-11-27 18:12:07

标签: apache-flink flink-streaming

我是Flink的新手,我正在尝试做一些练习,当我使用带有kafka连接器的窗口时,我遇到了一个问题。

代码是这样的:

val env: StreamExecutionEnvironment = StreamExecutionEnvironment.getExecutionEnvironment

.....

// a KeyedStream with name as the key
val eventsStream: KeyedStream[CustomedObject, String] = env
  .addSource[CustomedObject](source.getSource)
  .keyBy(c.get("name"))

// defines a Sliding window assigner with event time
val windowedStream: WindowedStream[CustomedObject, String, TimeWindow] = eventsStream.window(SlidingEventTimeWindows.of(Time.seconds(2L), Time.seconds(1L)))

// applys a window function
val result = windowedStream.apply(
  (key, window, input: Iterable[CustomedObject], out: Collector[(String, TimeWindow)]) => {
    out.collect((key, window))
  }
)

问题:当我尝试 eventsStream.print()时,控制台中有输出,但是当我尝试 result.print()时,没有输出

的相关信息: 密钥存在并且在每个事件中都有价值

有人可以告诉我为什么没有每个窗口的内容输出?

2 个答案:

答案 0 :(得分:2)

当流的水印到达窗口的末尾时,将触发事件时间窗口。如果没有发生,那么水印可能存在问题。源需要注意生成适当的水印,或者您需要在应用程序中实现它。有关这些主题的详情,请参阅event timewatermarks

更新了摘要,希望避免任何混淆:

事件时间时间戳和水印的长度通常表示自Epoch以来的毫秒数,但事件时间是逻辑的,单调增加的时钟,而Flink并不关心值实际代表什么。

与处理时间不同,处理时间不断向前推进,事件时间一直保持不变,直到 watermarks 推进。当前水印是事件时间时钟的当前值,它通常落后于到目前为止看到的某个有限延迟的最大时间戳(此延迟是在事件被认为迟到之前将被容纳的最大无序)。 / p>

当您的应用程序在事件时间运行时,Flink需要知道与每个流元素关联的时间戳以及当前水印。 时间戳提取器水印生成器为此角色提供服务,Flink提供了两种内置方法,可以进行扩展。

除非您的数据源已经为您提取了AssignerWithPunctuatedWatermarksAssignerWithPeriodicWatermarks的时间戳,否则您需要实现Flink将在每个流元素上调用的extractTimestamp(MyEvent element, long previousElementTimestamp)方法它的时间戳。

这两者之间的区别在于 AssignerWithPunctuatedWatermarks 具有为每个流元素调用的checkAndGetNextWatermark()方法,期望某些元素是特殊的(如标点符号),并且这些特殊元素将用于生成水印。相比之下,使用 AssignerWithPeriodicWatermarks ,每隔ExecutionConfig.getAutoWatermarkInterval()毫秒调用一次getCurrentWatermark()方法来生成水印,期望某些状态保持为副作用调用extractTimestamp()可用于生成水印(BoundedOutOfOrdernessTimestampExtractor,这是通过记住到目前为止在流中看到的最大时间戳来实现的。)

答案 1 :(得分:0)

@alpinegizmo非常感谢你的回复,你是对的,我想为其他新人做一个小小的总结。

要注意两点:

  1. 时间戳和水印定义为 longs ,代表     自纪元(1970年1月1日午夜)以来毫秒,这意味着它应该像1511866730000L
  2. AssignerWithPunctuatedWatermarks和之间的区别     AssignerWithPeriodicWatermarks
  3. AssignerWithPunctuatedWatermarks :如果元素已经在创建时带有时间戳,您希望将它们用作时间戳,因此请使用AssignerWithPunctuatedWatermarks,因为它是" 间断&#34 ;;

    AssignerWithPeriodicWatermarks :使用此类以定期间隔生成水印。最多每xx毫秒(通过ExecutionConfig.getAutoWatermarkInterval()配置),系统将调用getCurrentWatermark()方法来探测下一个水印值。因此,系统自动为您生成每个事件的时间间隔,它是" periodic "。

    我对标点符号和周期性感到困惑,我认为标点符号表示时间戳会保存在某处,它是永久存储。

    我希望这可以帮助其他新手!