Flink 的windowing 操作是在window 末尾处理元素还是做滚动处理?

Does Flink's windowing operation process elements at the end of window or does it do a rolling processing?

我在理解 windowing 在 Flink 内部实现的方式时遇到了一些问题,找不到任何深入解释这一点的文章。在我看来,有两种方法可以做到这一点。考虑一个简单的 window wordcount 代码如下

env.socketTextStream("localhost", 9999)
    .flatMap(new Splitter())
    .groupBy(0)
    .window(Time.of(500, TimeUnit.SECONDS)).sum(1)

方法 1:将所有事件存储 500 秒,在 window 结束时,通过对存储的事件应用求和运算来处理所有事件。

方法二:我们用一个计数器来存储每个window的滚动总和。当 window 中的每个事件到来时,我们不存储单个事件,而是继续将先前存储的计数器加 1,并在 window.

结束时输出结果

有哪位大侠帮忙了解下Flink在现实中使用的是上面的哪些方法(或者其他方法)。原因是,这两种方法各有利弊,理解这一点对于正确配置集群资源很重要。 例如:方法 1 似乎非常接近批处理,并且可能存在与每 500 秒间隔处理一次峰值相关的问题,否则处于空闲状态等,而方法 2 需要在所有任务管理器之间维护一个公共计数器。

sum 是此处提到的缩减函数 (https://nightlies.apache.org/flink/flink-docs-master/docs/dev/datastream/operators/windows/#reducefunction)。在内部,Flink 会对每个输入元素应用 reduce 函数,并将减少的结果简单地保存在 ReduceState.

对于其他 windows 函数,例如 windows.apply(WindowFunction)。没有聚合,因此所有输入元素都将保存在 ListState.

这篇关于windows流的文档(https://nightlies.apache.org/flink/flink-docs-master/docs/dev/datastream/operators/windows/#window-functions)提到了Flink中如何处理内部元素。