我尝试在Apache Flink中实现一种窗口函数。例如,我想取元素1 - 5并对它们进行处理,然后我想取元素6 - 10,依此类推。
目前我有一个数据集,其数据是由CSV文件派生的:
DataSet<Tuple2<Double, Double>> csvInput = env
.readCsvFile(csvpath)
.includeFields(usedFields)
.types(Double.class, Double.class);
现在我想要一个包含这个数据集的前5个元素的子集。我可以用first
-function:
DataSet<Tuple2<Double, Double>> subset1 = csvInput.first(5);
但是如何得到后面的5个元素呢?有没有类似startAt
的函数,我可以用?例如:
DataSet<Tuple2<Double, Double>> subset2 = csvInput.first(5).startAt(6);
我没有在Apache Flink Java API中找到任何东西。最好的存档方式是什么?
Matthias Sax给出了用于窗口的流API的良好指针。如果应用程序遵循流分析模型,那么流API绝对是正确的选择。
这里有更多关于流窗口的资源:https://ci.apache.org/projects/flink/flink-docs-master/apis/streaming_guide.html#window-operators
Windows中的批处理API
也可以在批处理API中手动应用某种形式的窗口。在应用windows时,应考虑以下事项:
-
大多数操作是并行的。当同时显示n元素时,这通常在每个并行分区独立发生。
-
没有隐含的元素顺序。即使在并行读取文件时,也可能是文件的后面部分被更快的并行读取线程读取,这些后面部分的记录到达得更早。因此,按到达顺序窗口化n元素只会给你一些n元素。
Window by Order in File (non - parallel)
在文件中按顺序打开窗口,您可以将输入设置为非并行(在源上使用setParallelism(1)
),然后使用mapPartition()
将窗口滑动到元素上。
按某个值(例如时间戳)排序的窗口
您可以通过对分区排序(sortPartition().mapPartition()
)或使用groupBy(...).sortGroup(...).reduceGroup(...)
对组进行窗口排序来取消分组(无键)。这些函数将元素按照要显示的值排序,并将数据滑动到窗口。
一些并行窗口(没有好的语义)
可以使用mapPartition()
并行读取并在数据流上滑动窗口。然而,如上所述,元素的并行执行和未定义顺序将为您提供一些窗口结果,而不是可预测的窗口结果。