Apache Beam捆绑问题

时间:2019-03-20 08:03:21

标签: apache-spark apache-beam

以下是我的问题,我想聚合一些存储在S3上的数据。作为流水线的初始输入,我使用了一个文本文件,其中包含应聚合的所有S3文件的路径。

 PCollection<String> readInputPipeline = p.apply("ReadLines", TextIO.read().from(options.getInputFile()));
 readInputPipeline = readInputPipeline.apply(ParDo.of(new ReadFromS3Mapper()));

输入文件有346k行。当我将此代码部署到Spark集群时,即使有许多内核可用,也似乎仅在2个Spark任务中发生,这仅发生在S3中。我有什么办法可以增加此操作的并行性?

enter image description here

我正在使用具有以下选项的主服务器(m3.xlarge)和核心计算机(R3.4xlarge)在Amazon的EMR上运行此

"spark-submit"
  "--driver-java-options='-Dspark.yarn.app.container.log.dir=/mnt/var/log/hadoop'",
  "--master", "yarn",
  "--executor-cores","16",
  "--executor-memory","6g"

PS:也许解决方案可能是我不应该在这种情况下进行这种昂贵的IO操作?

2 个答案:

答案 0 :(得分:0)

Spark决定如何分割输入,在这里决定一遍遍遍整个文件,因为它很小。

我在distcp application中做了类似的事情;它使用Spark的ParallelCollectionRDD类来明确告诉spark将清单一一拆分。

该类足以让您执行类似的操作-您可能必须在本地将初始文本文件读取到列表中,然后将列表传递给ParallelCollectionRDD构造函数

答案 1 :(得分:0)

回复较晚,但我调查了Beam在2.16.0版本中的作用。

在第一个TextIO.read()之后,您将获得2个任务-我怀疑您最初的34.6万行文件列表已被分成两个分区。此行为由TextIO内部的desiredBundleSize控制,该代码硬编码为64MB。

在Spark中,您的操作ReadFromS3Mapper将“融合”到到达的记录中,并且您将始终停留在两个分区中。

如果要保留相同的代码,可以在两个转换之间强制重新分区:

PCollection<String> allContents = p.apply("ReadLines", TextIO.read().from(options.getInputFile()))
        .apply("Repartition", Reshuffle.viaRandomKey())
        .apply(ParDo.of(new ReadFromS3Mapper()));

作为替代,TextIO和FileIO实用程序中提供了许多有趣的模式。有一个与您的almost exactly相匹配的示例(暗含reshuffle)。