在Flink管道中集成不可并行化的任务和高内存需求

时间:2015-12-08 13:12:04

标签: apache-flink

我在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()
  1. 这个解决方案看起来很不自然。是否有直接的方法将此任务合并到我的Flink管道中?
  2. 我在another thread中读到collect()函数不应该用于大型数据集。我相信将数据集收集到一个列表然后一个数组并不是并行发生这一事实现在不是我最大的问题,但是您是否仍然希望将我上面称为input的内容写入文件并构建一个数组那个?
  3. 我还看到options在flink中配置托管内存。原则上,有可能以某种方式对其进行调整,以便为昂贵的操作留下足够的堆。另一方面,我担心拓扑中所有其他运营商的性能可能会受到影响。你对此有何看法?

1 个答案:

答案 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会自动将中间结果溢出到光盘。