Apache spark Spark RDD foreachPartition到S3

Apache spark Spark RDD foreachPartition到S3,apache-spark,amazon-s3,Apache Spark,Amazon S3,我目前正在探索火花。我面临着以下任务-获取一个RDD,根据特定标准对其进行分区,然后在S3存储桶中的不同文件夹中写入多个文件 在上传到S3部分之前,一切都很好。我已经阅读了与此问题相关的所有问题,发现我可以使用AmazonS3Client或rdd的saveToTextFile方法。我面临两个问题: 如果我使用AmazonS3Client我会得到一个java.io.NotSerializableException,因为代码是从Spark驱动程序发送到worker的,它需要序列化,而AmazonS3

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

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

  • 如果我使用
    AmazonS3Client
    我会得到一个
    java.io.NotSerializableException
    ,因为代码是从Spark驱动程序发送到worker的,它需要序列化,而AmazonS3Client显然不支持这一点

  • 如果我使用
    saveToTextFile
    我会面临类似的问题。当我进入
    foreachPartition
    循环时,我需要得到
    Iterable[T]
    (在本例中是
    p
    ),因此如果我想使用
    saveToTextFile
    ,我需要创建Iterable的RDD,从而实现
    并行化。问题是SparkContext
    sc
    也(理所当然地)没有序列化

  • rdd.foreachPartition{p=>
    sc.parallelize(p.toSeq).saveAsTextFile(s“s3n://”)
    }


    任何帮助都将不胜感激。

    没有必要这样做。您可以将
    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)