flink watermark的原理和本质
在Flink中,watermark称为水位线或水印,是flink为流式数据每隔一段时间打上的一个标记。
watermark 通过额外的时间戳来控制窗口激活的时间,主要是为了解决数据乱序到达的问题。flink可以每来一个消息就处理一次,但是有时我们需要做一些聚合类的处理,例如:在过去的1分钟内有多少用户点击了我们的网页。聚合类处理带来了新的问题,比如乱序/延迟。其解决方案就是 watermark 和 allowedLateness。
当flink中的算子接收到watermark时,它明白早于该时间的消息已经完全抵达计算引擎,即假设不会再有时间小于水位线的事件到达,从而开始计算。
watermark本质是什么?
watermark是基于已经收集的消息来估算是否还有消息未到达,本质上是一个时间戳。时间戳反映的是事件发生的时间,而不是事件处理的时间。从flink的源码就能看出来,watermark唯一有意义的成员变量就是 timestamp:
public final class Watermark extends StreamElement {
public static final Watermark MAX_WATERMARK = new Watermark(Long.MAX_VALUE);
private final long timestamp;
public Watermarklong timestamp) {
this.timestamp = timestamp;
}
public long getTimestamp() {
return timestamp;
}
}
watermark如何解决乱序/延迟问题?
watermark实际上作为数据流的一部分随数据流流动。可以把watermark理解为一个水位线,这个水位线在不断的变化。当flink中的算子接收到watermark时,它明白早于该时间的消息已经完全抵达计算引擎,即假设不会再有时间小于水位线的事件到达。这个是触发窗口计算的基础,只有水位线越过窗口对应的结束时间,窗口才会关闭并开始进行计算。