Spark:stage X包含运行sc.binaryFiles()

时间:2017-09-14 15:33:05

标签: scala apache-spark amazon-s3

我正在尝试加载存储在S3上的〜1M文件集。运行sc.binaryFiles("s3a://BUCKETNAME/*").count()

我得到了WARN TaskSetManager: Stage 0 contains a task of very large size (177 KB). The maximum recommended task size is 100 KB。接下来是失败的任务

我看到它为这个阶段推断出128个分区,这个分区太低了,请注意,当在400K文件桶上运行相同的命令时,分区数量将会高得多(约2K分区)并且操作将成功。< / p>

设置较高的minPartitions没有帮助; 设置较高的spark.default.parallelism也无济于事。

唯一有效的方法是创建每个1000个文件的多个较小的RDD,并在它们上运行sc.union,这种方法的问题在于它太慢了。

如何减轻这个问题?

更新: 继续看看BinaryFileRDD.getPartitions()中的分区数是如何解决的,这让我得到了这段代码:

  def setMinPartitions(sc: SparkContext, context: JobContext, minPartitions: Int) {
    val defaultMaxSplitBytes = sc.getConf.get(config.FILES_MAX_PARTITION_BYTES)
    val openCostInBytes = sc.getConf.get(config.FILES_OPEN_COST_IN_BYTES)
    val defaultParallelism = sc.defaultParallelism
    val files = listStatus(context).asScala
    val totalBytes = files.filterNot(_.isDirectory).map(_.getLen + openCostInBytes).sum
    val bytesPerCore = totalBytes / defaultParallelism
    val maxSplitSize = Math.min(defaultMaxSplitBytes, Math.max(openCostInBytes, bytesPerCore))
    super.setMaxSplitSize(maxSplitSize)
  }

我跟着计算,它仍然没有意义,我应该得到一个更大的数字。

所以我试图减少config.FILES_MAX_PARTITION_BYTES配置(spark.files.maxPartitionBytes) - 这确实增加了分区的数量,并使工作完成,但是我仍然得到了原始警告(有点但是,分区的munber比在400K文件集上运行时要小。

1 个答案:

答案 0 :(得分:0)

问题根源在于文件的大小:令我惊讶的是,s3中的文件没有正确上传,它们的大小比它们应该小了100倍。这导致setMinPartitions计算包含大量小文件的拆分。每个拆分本质上是一个逗号分隔的文件路径字符串,因为每个拆分有很多文件,我们有一个非常长的指令字符串,应该传递给所有工作人员。这使网络负担沉重,导致整个流程失败。将spark.files.maxPartitionBytes设置为较低的值可以解决问题。