Spark RDD foreachPartition到S3

时间:2016-08-03 14:10:56

标签: apache-spark amazon-s3

我正在探索Spark。我面临以下任务 - 获取RDD,根据特定条件对其进行分区,然后在S3存储桶中的不同文件夹中写入多个文件。

在我们上传到S3部分之前,一切都很好。我已经在SO上阅读了所有与此问题相关的问题,并发现我可以使用AmazonS3ClientsaveToTextFile方法进行RDD。我面临两个问题:

  1. 如果我使用AmazonS3Client,我会得到一个java.io.NotSerializableException,因为代码是从Spark驱动程序发送给工作人员的,所以需要对其进行序列化,显然AmazonS3Client并不是这样。支持那个。

  2. 如果我选择saveToTextFile,我会面临类似的问题。当我进入foreachPartition循环时,我需要Iterable[T](在本例中为p),所以如果我想使用saveToTextFile,我需要创建一个RDD因此可以转移parallelize。问题是SparkContext sc也是(理所当然地)没有序列化。

  3. rdd.foreachPartition { p => sc.parallelize(p.toSeq).saveAsTextFile(s"s3n://") }

    非常感谢任何帮助。

1 个答案:

答案 0 :(得分:5)

没有必要这样做。您可以将saveAsTextFile与rdd:

一起使用
rdd.saveAsTextFile(s"s3n://dir/to/aux/file")

saveAsTextFile将在包含文件许多部分的文件夹中写入S3(与分区一样多的部分)。然后,如果需要,您可以合并到单个文件:

  def mergeToS3(srcPath: String, dstPath: String, sc: SparkContext): Unit = {
    val hadoopConfig = sc.hadoopConfiguration
    val fs = FileSystem.get(new URI(srcPath), hadoopConfig)
    FileUtil.copyMerge(fs, new Path(srcPath), fs, new Path(dstPath), true, hadoopConfig, null)
  }

  mergeToS3("s3n://dir/to/aux/file", "s3n://dir/to/singleFile",sc)