如何拥有一个忽略最近事件的真正滑动窗口?
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
中同时使用ProcessWindowFunction
和WindowFunction
。两者有什么区别?显然接口是不同的,但是在运行时有什么区别呢?
以上内容的更多信息:似乎一个通过 InternalSingleValueProcessWindowFunction 维护窗口的上下文,而另一个则没有,但它有成本吗?如果ProcessWindowFunction
s 看起来像一个超集,我们为什么需要WindowFunction
s?
ProcessWindowFunction 是最近添加到 API 中的,并且确实是 WindowFunction 的超集。 WindowFunction 可能有一天会被弃用。以上是关于如何拥有一个忽略最近事件的真正滑动窗口?的主要内容,如果未能解决你的问题,请参考以下文章