为什么apache flink需要水印来进行事件时处理?

txu3uszq  于 2021-06-21  发布在  Flink
关注(0)|答案(1)|浏览(324)

有人能正确解释事件时间戳和水印吗。我从医生那里听懂了,但不太清楚。一个真实的例子或外行的定义会有所帮助。另外,如果可能的话,请给出一个例子(以及一些可以解释它的代码片段)

lxkprmvk

lxkprmvk1#

下面的例子说明了为什么我们需要水印,以及它们是如何工作的。
在本例中,我们有一个带有时间戳的事件流,这些事件的到达有些无序,如下所示。显示的数字是事件时间戳,表示这些事件实际发生的时间。第一个到达的事件发生在时间4,然后是更早发生的事件,发生在时间2,依此类推:

··· 23 19 22 24 21 14 17 13 12 15 9 11 7 2 4 →

现在假设我们正在尝试创建一个流分类器。这意味着一个应用程序在流到达时处理流中的每个事件,并发出一个包含相同事件的新流,但按事件的时间戳排序。
一些观察结果:
(1) 流分类器看到的第一个元素是4,但我们不能立即将其作为已排序流的第一个元素发布。它可能已经到达的秩序,和较早的事件可能尚未到来。事实上,我们对这个流的未来有一些上帝般的知识,我们可以看到,我们的流分类器至少应该等到2号到达后才能产生任何结果。
结论:一些缓冲和一些延迟是必要的。
(2) 如果我们做错了,我们可能会永远等下去。首先,我们的应用程序看到了时间4的一个事件,然后是时间2的一个事件。时间戳小于2的事件是否会到达?也许 吧。也许不是。我们可以永远等待,却永远看不到1。
结论:最终,我们必须勇敢地发射出2作为排序流的开始。
(3) 然后我们需要的是某种策略,它定义了对于任何给定的时间戳事件,何时停止等待较早事件的到来。
这正是水印所做的-它们定义了何时停止等待更早的事件。
flink中的事件时间处理依赖于水印生成器,该生成器将特殊的时间戳元素插入流中,称为水印。
什么时候我们的流分拣机应该停止等待,并推出2开始分拣流?水印到达时的时间戳为2或更大。
(4) 我们可以想象不同的策略来决定如何生成水印。
我们知道每一个事件都是经过一定的延迟才到达的,而且这些延迟是不同的,所以有些事件的延迟比其他的要多。一个简单的方法是假设这些延迟是有界的一些最大延迟。flink将此策略称为有界无序水印。很容易想象更复杂的水印方法,但对于许多应用程序来说,固定延迟就足够了。
如果您想构建一个像流分类器这样的应用程序,flink的 ProcessFunction 是正确的构造块。它提供对事件时间计时器的访问(也就是说,根据水印的到达触发的回调),并具有钩子来管理缓冲事件所需的状态,直到轮到事件被发送到下游。

相关问题