我正在构建Flink流应用程序,并且希望使用事件时间,因为它可以确保所有设置的计时器在历史数据失败或重播时都将确定性地触发。事件时间的问题是时间只有在事件发生时才向前移动。我们的数据源(物理传感器)有时只生成很少的数据,因此有时单个数据点可能会打开一个五分钟的聚合窗口,但是下一个数据点是在20分钟后,因此窗口关闭并在很晚后发出输出记录。
我们为此提出的解决方案是使用安排为每X分钟运行一次的AWS lambda函数,该函数将虚拟事件输出到Flink读取的Kinesis流中,从而迫使生成水印,从而提前时间。
[我的担心是,只有在水印真正是全局的时,这才起作用,这意味着单条心跳消息可以导致水印的产生,从而延长了Flink应用程序中每个操作员/任务的事件时间,而Flink应用程序使用源自此流。该文档使我相信Flink会从源中读取内容,其中每个并行读取运算符都会生成自己的水印,然后下游运算符(例如窗口)将所看到的各种水印中的最小值最小化。如果真是这样,这对我来说似乎很麻烦,因为每个并行水印生成器都需要一个虚拟心跳事件,但是我无法控制哪些节点从流中读取我的心跳消息。
所以,我的问题是,下游操作员如何精确地使用水印来提高事件时间,是否可以将单个虚拟消息添加到运动流中,从而在整个ENTIRE Flink应用程序中提高事件时间?
如果没有,我如何强制事件时间向前发展?
但是,我认为您根本不需要使用Lambda函数。您可能正在寻找的是周期性添加水印而不是标点符号。从您的帖子中,我假设您当前正在执行的操作只是使用AssignerWithPunctuatedWatermark
,它将在元素到达流中时分配水印,但是还有另一个选项是AssignerWithPeriodicWatermark
,它使您可以设置一些间隔即使实际上没有元素在流动,也可用于生成水印。您可以在docs中找到有关此信息的更多信息。