假设我们有一个 TumblingEventTimeWindow ,其大小为5分钟。我们有包含 2个基本信息信息的事件:
在此示例中,我们在 12:00 PM工作者计算机的挂钟时间上启动了 Flink 拓扑(当然,工作者可以没有同步时钟,但这是超出此问题的范围)。该拓扑包含一个处理操作员,其负责总结属于每个窗口的事件的值以及与该问题无关的KAFKA接收器。
在这种情况下,几个事件到达 Flink运算符,它们的事件时间戳跨越12:01 - 12:09
。此外,事件时间戳与我们的处理时间相对应(在下面的X轴中显示)。由于我们正在处理 EVENT_TIME 特性,因此应通过事件的 event timestamp 确定事件是否属于某个事件。
在该流程中,我假定了两个滚动窗口的边界,分别是12:00 -- 12:05
和12:05 -- 12:10
因为我们已在 12:00 开始执行拓扑。如果该假设是正确的(我希望不是),那么在回填情况下会发生什么情况,在这种情况下,发生了多个 old 事件且带有更旧的事件时间戳,我们又在 12:00 开始了拓扑? (年龄足够大,以致我们的迟到津贴不包括这些费用)。类似于以下内容:
上一个问题的答案也将解决此问题,但是我认为在此处明确提及它会有所帮助。假设我有这个 TumblingEventTimeWindow ,大小为5分钟。然后在 12:00 ,我启动了一项回填工作,该工作将许多事件赶往Flink运算符,该运算符的时间戳覆盖范围10:02 - 10:59
;但这是一项回填工作,因此整个执行过程大约需要 3分钟。
作业会分配 12个单独的窗口并根据事件的事件时间戳正确地填充它们吗?这 12个窗口的边界是什么?我是否会以 12个输出事件结尾,每个事件具有每个分配窗口的总结值?
对于这种逻辑和运算符的自动化测试,我也有一些担忧。操纵处理时间的最佳方法是触发某些行为,从而塑造所需窗口的边界以进行测试。特别是因为到目前为止,我所读到的关于利用Test Harnesses
的内容似乎有点令人困惑,并且可能会导致一些混乱的代码,而这些代码并不那么容易阅读:
我在这方面学到的大部分知识和一些困惑的根源可以在以下地方找到:
Tumbling
,Sliding
,Session
等)工作?!非常感谢您的帮助,如果您对这些概念及其内部运作有更好的参考,请告诉我。
如果您使用事件时间语义来运行Job,则在窗口运算符上的处理时间是完全不相关的
那是正确的,我理解这一部分。一旦处理了EVENT_TIME
特性,您就在语义/逻辑上与处理时间脱节了。我延长处理时间的原因是我对以下关键问题感到困惑,这对我来说仍然是个谜:
窗口边界如何计算?!
也非常感谢您澄清out-of-orderness
和lateness
之间的区别。我正在处理的代码完全被误用(使从BoundedOutOfOrdernessTimestampExtractor
继承的类的构造函数参数被命名为maxLatency
)使我失望:/
考虑到这一点,让我看看我是否能够正确理解水印的计算方式和何时丢弃事件 strong>(或侧面输出):
max-event-time-seen-so-far - max-out-of-orderness-allowed
max-event-time-seen-so-far - allowed-lateness
max-event-time-seen-so-far
在任何一种情况下,无论其事件时间戳小于或等于current-watermark
的事件,被丢弃(侧面输出),对吗?!
这带来了一个新问题。您何时想使用out of orderness
而不是lateness
?由于在这些情况下当前水印计算(在数学上)可以是相同的。当您同时使用两者时会发生什么(甚至有意义)?!
这仍然是我的主要谜团。鉴于以上所有讨论,让我们回顾我提供的具体示例,看看如何确定窗口的边界。假设我们有以下情形(事件的形式为(value, timestamp)
):
DataStream
的{{1}},其持续时间为 2分钟 BoundedOutOfOrdernessTimestampExtractor
maxOutOfOrderness
注意:如果您不能同时拥有allowedLateness
和out of orderness
,或者没有有意义,请仅考虑lateness
在上面的示例中。
最后,能否请您布置窗口,将为其分配一些事件和,请指定这些窗口的边界( 开始和结束窗口的时间戳)。我假设边界也由事件的时间戳确定,但是要在像这样的具体示例中弄清楚边界是很棘手的。
再次,非常感谢,非常感谢您的帮助:)
答案 0 :(得分:0)
水印:据我了解,Flink和Spark结构化流中的水印定义为(最大事件时间戳,到目前为止可以看到-允许延迟)。任何事件时间戳小于或等于该水印的事件都将被丢弃并在结果计算中忽略。
这是不正确的,可能是造成混淆的原因。乱序和延迟是Flink中的不同概念。使用BoundedOutOfOrdernessTimestampExtractor
时,水印为max-event-timestamp-seen-so-far - max-out-of-orderness
。 Flink文档[1]中有更多关于允许延迟的信息。
如果您使用事件时间语义来运行Job,则在窗口运算符上的处理时间是完全不相关的:
window end time -1
),就会触发current watermark - allowed lateness
的事件将被丢弃或发送到后期数据端输出[1] 这意味着,如果您在12:00 pm(处理时间)开始工作并开始提取过去的数据,则水印也会(甚至更早)出现。因此,配置的allowedLateness
是无关紧要的,因为相对于偶数时间而言,数据并不晚。
另一方面,如果您首先从12:00 pm提取一些数据,然后从10:00 pm提取数据,则水印在提取旧数据之前已经提前到〜12:00pm。在这种情况下,晚上10:00起的数据将是“晚期”。如果它晚于配置的allowedLateness
(默认= 0),则将其丢弃(默认)或发送到侧面输出(如果已配置)[1]。
希望这会有所帮助。
康斯坦丁