我在这里阅读了关于 Flink 的窗口分配器: https://ci.apache.org/projects/flink/flink-docs-stable/dev/stream/operators/windows.html#window-assigners ,但我找不到任何解决方案来解决我的问题。
作为我项目的一部分,我需要一个窗口,计时器将在给定键的第一个元素时启动,并将关闭并在 X 分钟后准备好处理。 例如:
第一个键 A 出现在 (hh:mm:ss( 00:00:02,我希望所有键 A 都将窗口化到 00:01:02,然后只有当键 A 作为输入时,1 分钟的计时器才会再次启动。
是否可以在 flink 中做类似的事情? 有解决方法吗? 希望我说得足够清楚。
一般来说,实现与第一个事件对齐而不是与纪元对齐的键控窗口是相当困难的,我相信这就是为什么 Flink 的窗口 API 不支持这一点的原因。问题在于,对于使用事件时间处理的无序流,随着较早事件的到达,您可能需要修改窗口何时开始以及何时结束的概念。例如,如果第一个键 A 到达 00:00:02,但一段时间后,具有键 A 的事件到达时时间戳为 00:00:01,现在窗口突然应该在 00:01:01 结束,而不是 00:01:02。如果与窗口长度相比,无序性很大,则处理此问题将变得非常复杂 - 例如,想象一下,00:00:01 的事件比 00:00:02 的事件晚 2 分钟到达。
与其尝试使用窗口 API 实现这一点,我会使用KeyedProcessFunction
.如果您只需要支持处理时间窗口,则这些关于乱序的担忧不适用,解决方案可能相当简单。将一个对象保持在键控状态就足够了,该对象可能是包含窗口中所有事件的列表,也可能是计数器或其他聚合器,具体取决于您要完成的操作。
当事件到达时,如果状态(对于此键(为 null,则此键没有打开的窗口。初始化状态(即,创建一个新的空列表,或将计数器设置为零(,并创建一个在适当时间触发的计时器。然后,无论状态是否为 null,都将传入事件添加到状态中(即,将其追加到列表中,或递增计数器(。
当计时器触发时,发出窗口的结果并将状态重置为 null。
另一方面,如果要使用事件时间窗口执行此操作,请先对流进行排序,然后使用相同的方法。请注意,您将无法处理延迟事件,因此请相应地规划水印(将延迟事件的可能性降低到可管理的水平(,或者采用更复杂的实现。