在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时,它明白早于该时间的消息已经完全抵达计算引擎,即假设不会再有时间小于水位线的事件到达。这个是触发窗口计算的基础,只有水位线越过窗口对应的结束时间,窗口才会关闭并开始进行计算。

标签: none

添加新评论