我正在尝试构建自己的BoundedOutOfOrdernessGenerator
实现,如Flink's documentation中所建议,鉴于水印似乎未正确更新,我在这样做时遇到了一些问题。 Windows永远不会触发,因为水印没有前进。
以下是一些相关的摘要,其中myWatermarkAssigner
是WatermarkGenerator
的实例:
主流:
dataLeft = dataLeft.assignTimestampsAndWatermarks(myWatermarkAssigner);
dataRight = dataRight.assignTimestampsAndWatermarks(myWatermarkAssigner);
DataStream<MyWindow> output = dataLeft
.keyBy("field")
.coGroup(dataRight.keyBy("field"))
.where(dataL -> dataL.id)
.equalTo(dataR -> dataR.id)
.window(TumblingEventTimeWindows.of(duration))
.apply(myProcessor);
生成器类:
public class WatermarkGenerator<T extends MyEvent> implements AssignerWithPeriodicWatermarks<T> {
private static final long serialVersionUID = 1L;
private long maxOutOfOrderness = 15000; // 15 seconds
private long currentMaxTimestamp;
public WatermarkGenerator(long maxTimeLag) {
this.maxOutOfOrderness = maxTimeLag;
}
@Override
public long extractTimestamp(MyEvent element, long previousElementTimestamp) {
long timestamp = element.eventTime.getTime();
currentMaxTimestamp = Math.max(timestamp, currentMaxTimestamp);
return timestamp;
}
@Override
public Watermark getCurrentWatermark() {
return new Watermark(currentMaxTimestamp - maxOutOfOrderness);
}
}
如果我在getCurrentWatermark()
内添加一个简单的日志,则会得到以下结果:
0
0
0
0
0
1557157602000 // First element just arrived
0
0
0
1557157602000
0
0
0
1557157602000
0
0
0
窗口永远不会触发,我知道这是因为水印有时为0,有些时候是正确的值。
这是否与以下事实有关:我为WatermarkGenerator
和dataLeft
使用了dataRight
的相同实例,而我只收到dataLeft
上的事件? / p>
另外,如果我改用像这样的水印使用系统时间,则Windows触发,并且管道的运行就像一个魅力:
// return new Watermark(currentMaxTimestamp - maxOutOfOrderness);
return new Watermark(System.currentTimeMillis() - maxOutOfOrderness);
作为最后的说明,我正在使用.setAutoWatermarkInterval(1000L)
,并且尝试使用the built-in BoundedOutOfOrdernessTimestampExtractor
implementation来获得相同的失败结果。