我想在Flink中根据历史事件计算基于窗口的平均值(或我定义的任何其他函数),因此流必须是事件时间(不是基于处理时间):
val env: StreamExecutionEnvironment = StreamExecutionEnvironment.getExecutionEnvironment
env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
我已经找到了如何在摄取时添加时间戳:
ctx.collectWithTimestamp(Datapoint(instrument, bid, ask), time.getMillis)
但是当我进行计算(应用函数)时,当我以与没有EventTime时相同的方式进行计算时,它不起作用。我已经阅读了一些关于水印的内容,我必须设置:
val avg = stream
.keyBy("instrument")
.timeWindow(Time.seconds(10))
.apply((key: Tuple, window: TimeWindow, values: Iterable[Datapoint], out: Collector[Datapoint])=>{
val avg = values.map(_.val).sum / values.size
val dp = Datapoint(key.getField[String](0), avg)
out.collect(dp)
})
avg.print()
env.execute()
有人为此做了一个简单的Scala示例吗?
的问候,
安德烈亚斯
答案 0 :(得分:0)
水印实际上是一个时间戳,其断言所有具有较早时间戳的事件(可能)已经到达。基于事件时间的Windows依赖于水印来了解窗口何时完成。到目前为止,最常见的水印策略是假设事件以一定的有限延迟到达。
如果您想在数据源中(在摄取过程中)发出水印,请参阅Source Functions with Timestamps and Watermarks,但它会像
一样简单ctx.emitWatermark(new Watermark(datapoint.getWatermarkTime))
另一方面,如果您想在源外处理此问题,请参阅Timestamp Assigners / Watermark Generators和Assigners allowing a fixed amount of lateness。你可以简单地做这样的事情:
stream
.assignTimestampsAndWatermarks(new BoundedOutOfOrdernessTimestampExtractor[Datapoint](Time.seconds(10))( _.getTimestamp ))
.keyBy("instrument")
...
我链接到的文档在Scala中有更详细的示例。