如何拥有一个忽略最近事件的真正滑动窗口?

Posted

技术标签:

【中文标题】如何拥有一个忽略最近事件的真正滑动窗口?【英文标题】:How to have a true sliding window that ignores recent events? 【发布时间】:2018-06-13 17:00:31 【问题描述】:

我试图构建一个类似于滑动窗口的窗口,并且:

计数事件,忽略从窗口结束到某个“延迟”的事件 每个事件仅触发一次 [事件 TS - 延迟 - 持续时间,事件 TS - 延迟] 中的事件输出计数 使用预聚合来避免保存所有事件。

窗口的参数是:

持续时间:窗口的持续时间 输出:要触发的事件的偏移量,从窗口末尾开始计数。类似于“幻灯片”。 延迟:要忽略的事件的偏移量,从窗口末尾开始计数。基本上忽略时间戳

我尝试的想法涉及使用滑动窗口:

持续时间:持续时间 + 输出 + 延迟 幻灯片:输出 每当事件 TS 处于 [窗口结束 - 输出,窗口结束] 时触发。这只会触发一个窗口。

现在的问题是:如何过滤事件以忽略“延迟”之前的事件?我想到了:

只有当事件 TS 位于正确边界之间时,聚合器才会对值求和。这是不可能的,因为 Windows 中的聚合器不能是 RichAggregateFunction,因此我无法访问窗口元数据。 这个假设正确吗?

预聚合:

典型的 sum reducer RichWindowFunction 使用托管状态来跟踪在“要忽略的区域”中看到了多少元素,并从收到的聚合器结果中减去该元素。问题是 getRuntimeContext().getState() 不是每个窗口都维护的,因此不能使用。 这个假设正确吗?

是否有我遗漏的替代方案或任何假设不正确?

【问题讨论】:

【参考方案1】:

我可能对细节有点迷失了,但也许我看到了解决方案。

似乎您可以使用自定义Trigger 在延迟之前和之后触发两次。然后使用ProcessWindowFunction with incremental aggregation,并使用per-window state 保存第一次触发的计数(稍后再减去)。

考虑到将所有这些组合在一起的复杂性,基于 ProcessFunction 和托管状态的解决方案可能会更简单。

【讨论】:

感谢大卫的迅速回复!我还没有尝试过,但我想它会起作用。我没有意识到你可以在WindowedStream#aggregate 中同时使用ProcessWindowFunctionWindowFunction。两者有什么区别?显然接口是不同的,但是在运行时有什么区别呢? 以上内容的更多信息:似乎一个通过 InternalSingleValueProcessWindowFunction 维护窗口的上下文,而另一个则没有,但它有成本吗?如果ProcessWindowFunctions 看起来像一个超集,我们为什么需要WindowFunctions? ProcessWindowFunction 是最近添加到 API 中的,并且确实是 WindowFunction 的超集。 WindowFunction 可能有一天会被弃用。

以上是关于如何拥有一个忽略最近事件的真正滑动窗口?的主要内容,如果未能解决你的问题,请参考以下文章

图解数据计算中的窗口概念

Spark:在流式查询中使用事件时间滑动窗口时出现问题

滑动窗口滚动条触发事件

Flink 大尺寸/小提前滑动窗口性能

pipelinedb 滑动窗口

滑动时间窗口的 F​​link 性能问题