有人可以正确解释事件时间戳和水印吗?我从文档中了解了这一点,但并不清楚。现实生活中的例子或外行人的定义会有所帮助。另外,如果可能的话,请举一个示例(以及一些可以解释它的代码段)。预先感谢
答案 0 :(得分:4)
下面是一个示例,说明了我们为什么需要水印以及它们如何工作。
在此示例中,我们提供了带有时间戳的事件流,这些事件有时会有些混乱,如下所示。显示的数字是事件时间时间戳,指示这些事件实际发生的时间。到达的第一个事件发生在时间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
是正确的构建块。它提供了对事件时间计时器(即根据水印的到达而触发的回调)的访问,并具有用于管理缓冲事件所需的状态的钩子,直到将事件发送到下游为止。