

SingleOutputStreamOperator<DataBean> watered = maped.assignTimestampsAndWatermarks(WatermarkStrategy.<DataBean>forBoundedOutOfOrderness(Duration.ZERO).withTimestampAssigner(new SerializableTimestampAssigner<DataBean>() {
@Override
public long extractTimestamp(DataBean dataBean, long l) {
return dataBean.getTs();
}
}));
assignTimestampsAndWatermarks,生成水印方法,底层的类,会不断的执行一个定时任务就是 调用 onPeriodicEmit()周期的发送watermark


同时我们看到还有一个onEvent(),在每次收到数据后都会调用一次onEvent方法,不断比较上次的watermark和本次watermark的大小,如果比上次的大就替换成为新的watermark

- 到这:第一次 assignTimestampsAndWatermarks 的逻辑就是
- assignTimestampsAndWatermarks这个方法内部,会每200ms会调用一次onPeriodicEmit()方法,onPeriodicEmit会output.emitWatermark()输出watermark(maxTimestamp),还有个onEvent的方法,onEvent每次收到数据后会根据数据时间和maxTimestamp取最大值,然后不断更新它,就会根据数据的情况一直生成新的watermark。
- 但是当到了数据处理环节后,就不再是这样了
- 到了数据处理环节后,每个数据 和 watermark都被包装成了一个StreamElement,每次处理的时候会根据数据类型进行判断,是watermark则更新当前时间,是数据则是正常流程,因此在下游这两个方法不是异步方法,而是同步阻塞的。
- 因此新的数据只能拿到上次的watermark时间。

本文深入探讨了Apache Flink中的水印策略,重点解析了`assignTimestampsAndWatermarks`方法。内容包括水印生成逻辑,如何周期性发送watermark以及数据处理环节中watermark和数据的同步处理方式。阐述了watermark在处理乱序事件中的作用,并指出在数据流处理过程中,新数据只能获取到上次的watermark时间。
642

被折叠的 条评论
为什么被折叠?



