4个角度轻松理解 Flink中的Watermark 4个角度轻松理解 Flink中的Watermark

Watermark 理解了,但是想讲给别人听, 总是讲不清楚,这篇让我理解了

原文:

当我们第一次接触 Flink 时往往会对其中的 watermark 感到困惑。但实际上 watermark 并不复杂。在本文中我们将通过一个简单的例子来说明为什么需要水印以及它们如何工作。

4个角度理解Flink中的watermark

在下文中的例子中,我们有一个带有时间戳的事件流,但是由于某种原因流中的事件并不是按顺序到达的。图中的数字代表事件发生的时间戳(Event-time)。第一个事件在时间4达到,它后面跟着的是发生在更早时间(时间 2)的事件,以此类推:

4个角度轻松理解 Flink中的Watermark
4个角度轻松理解 Flink中的Watermark

注意这是一个按照事件时间(Event-time)处理的例子,上面所述的时间戳所表示的是事件真实发生时间,而非事件处理的时间(Processing-Time) 。事件时间(Event-Time)处理的强大之处在于,无论是在处理当前的数据还是重新处理历史(数据重放)的数据,基于事件时间创建的流计算应用都可以保证最终执行结果是一致的。

假设我们现在正在尝试创建一个流计算排序算子。即将一个乱序到达的事件流按照事件时间进行顺序输出。数据流中的第一个元素的事件时间是 4,但是我们不能直接将它作为排序后数据流的第一个元素进行输出。因为数据是乱序到达的,也许有一个更早发生的数据还没有到达。实际上,我们在上面的例子中可以提前预知到这个流中元素2 的事件事件比4更早,我们的排序算子至少要等到 2 这条数据的到达后再做输出。

有缓存就必然有延迟

数据流中的第一个元素的事件时间是 4,但是我们不能直接将它作为排序后数据流的第一个元素进行输出。因为数据是乱序到达的,也许有一个更早发生的数据还没有到达。实际上,我们在上面的例子中可以提前预知到这个流中元素2 的事件事件比4更早,我们的排序算子至少要等到 2 这条数据的到达后再做输出。

必须勇敢地输出排序流的第一个结果

如果我们假设事件2已经达到,而且我们相信2之前还有更早的事件需要等待,在上面例子中的数据流中, 实际上已经没有比2更早的事件了,我们可能会永远等待下去。总之,我们的应用程序不能保证一定有更早的数据还未到达,所以不能无条件的等下去。

watermark 定义了何时不再等待更早的数据

我们需要某种策略用于定义了对于任何带事件事件的数据流,何时停止等待更早数据的到来。

Flink 中的事件时间处理依赖于一种特殊的带时间戳的元素,称为 watermark,它们会由数据源或是 watermark 生成器插入数据流中。具有时间戳 t 的 watermark 可以被理解为断言了所有时间戳小于或等于 t 的事件都(在某种合理的概率上)已经到达了。

何时我们的排序算子应该停止等待,然后将事件 2 作为首个元素输出?答案是当收到时间戳为 2(或更大)的 watermark 时。

设想不同的策略来生成 watermark。

我们知道每个事件都可能会延迟一段时间才到达且这些延迟差异会比较大,有些事件会比其他事件延迟更多。一种简单的方法是假设这些延迟不会超过某个最大值。Flink 把这种策略称作 "有界无序生成策略"(bounded-out-of-orderness)。当然也有很多更复杂的方式去生成 watermark,但是对于大多数常规应用来说,固定延迟方式已经足够了。

原文: https://mp.weixin.qq.com/s/NKt_2F-r0DTxxlQWen6uEA

总结

watermark定义了什么时候不用等待更早的数据.

假设现在时间戳是100秒的数据到了, 我们还等待到什么时候才开始计算呢?

要等到97秒的数据, 90秒的数据,还是50秒的数据呢?

这时候就要设定规则了.

我规定, 100秒的数据到了后,我再等待3秒钟, 97秒的数据到了,我就开始计算.