我们有一个大约90 GB的输入数据源(它可以是CSV或XML,它并不重要),它包含已经排序的数据列表。为简单起见,您可以将其视为具有两列:时间列和字符串列。此文件中的数亿行已按时间列按升序排序。
在我们的Google云DataFlow中,我们已将每一行建模为Pcollection中的元素,并且我们将DoFn转换应用于字符串字段(例如,计算字符串中大写的字符数等)。这很好。
然而,我们需要应用一段时间(例如五分钟)应该计算的函数,并且重叠一分钟。因此,我们正在考虑使用滑动窗口函数(即使数据有界)。
但是,需要在这些五分钟窗口上应用的计算逻辑假定数据按时间字段逻辑(即升序)排序。我的理解是,即使使用这些窗口函数,也不能假设在每个窗口中P集合对象都以任何方式排序 - 因此需要手动迭代每个P集合并重新排序它们,对吧?然而,这似乎是对计算能力的巨大浪费,因为传入的数据已经包含有序数据。那么有没有办法教授/告知谷歌云数据流输入数据的订购情况,以便即使在窗口内维护该订单呢?
在一个小问题上,我有另一个问题:我的理解是,如果数据源是无界限的,那么从来没有"整体聚合"将要执行的函数,因为它从来没有真正有意义(因为传入的数据没有结束);但是,如果对有界数据使用窗口函数,则存在真实的结束状态,其对应于从CSV文件读取所有数据的时间。因此,有一种方法可以告诉Google云数据流在读入所有数据后进行最终计算,即使我们使用窗口函数来分割数据吗?
答案 0 :(得分:3)
SlidingWindows听起来像是解决问题的正确方法。传输数据的排序不会在GroupByKey中保留,因此通知Dataflow当前没有用处。但是,批处理Dataflow运行器已经按时间戳排序,以便有效地实现窗口化,因此对于像SlidingWindows这样的简单窗口,您的代码将按顺序查看数据。
如果要在对有界数据集进行某些窗口计算后进行最终计算,可以再次将数据重新窗口化到全局窗口中,然后再进行最终聚合:
p.apply(Window.into(new GlobalWindows()));