我在Yarn Cluster中使用Flink来处理使用各种源和接收器的数据。在拓扑中的某个点上,存在无法并行化的操作,并且还需要访问大量内存。实际上,我在此步骤中使用的API需要以数组形式输入。现在,我已经实现了像
这样的东西ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();
DataSet<Pojo> input = ...
List<Pojo> inputList = input.collect();
Pojo[] inputArray = inputList.toArray();
Pojo[] resultArray = costlyOperation(inputArray);
List<Pojo> resultList = Arrays.asList(resultArray);
DataSet<Pojo> result = env.fromCollection(resultList);
result.otherStuff()
collect()
函数不应该用于大型数据集。我相信将数据集收集到一个列表然后一个数组并不是并行发生这一事实现在不是我最大的问题,但是您是否仍然希望将我上面称为input
的内容写入文件并构建一个数组那个?答案 0 :(得分:1)
您可以使用代理键替换“collect-&gt; array-&gt; expensiveOperation-&gt; array-&gt; fromCollection”步骤,使用具有所有元组的唯一值的代理键,以便获得只有一个分区。这就像Flink一样。
在昂贵的操作中,实现为GroupReduceFunction
,您将获得数据的迭代器。如果您不需要“一次”访问所有数据,那么您也可以安全地堆积空间,因为您不需要将所有数据保存在内部减少(但这当然取决于您的昂贵操作计算的内容)。
作为替代方案,您也可以在没有之前reduce()
的情况下致电groupBy()
。但是,您没有获得迭代器或输出收集器,只能计算部分聚合。 (参见https://ci.apache.org/projects/flink/flink-docs-release-0.10/apis/programming_guide.html#transformations中的“减少”)
使用Flink样式操作的优点是数据保留在集群中。如果您collect()
将结果转移到客户端,则会在客户端中执行代价高昂的操作,并将结果转移回群集。此外,如果输入很大,Flink会自动将中间结果溢出到光盘。