Apache spark 在每次映射调用时触发反序列化对象

Apache spark 在每次映射调用时触发反序列化对象,apache-spark,Apache Spark,我试图创建一个spark RDD,每个文件一行,用于存储在s3中的一组文本文件。我通过创建AmazonS3的实例来获取文本文件内容。我已经围绕这个S3客户机创建了一个可序列化的包装器,以便可以在spark的映射函数中使用它: class SerializableAmazonS3 implements java.io.Serializable { public transient AmazonS3 client; public AmazonS3 create() {

我试图创建一个spark RDD,每个文件一行,用于存储在s3中的一组文本文件。我通过创建
AmazonS3
的实例来获取文本文件内容。我已经围绕这个S3客户机创建了一个可序列化的包装器,以便可以在spark的映射函数中使用它:

class SerializableAmazonS3 implements java.io.Serializable {

    public transient AmazonS3 client;
    public AmazonS3 create()
    {
        AmazonS3ClientBuilder builder = AmazonS3Client.builder().withRegion(REGION).withCredentials(new ProfileCredentialsProvider());
        return builder.build();
    }

    private void readObject(ObjectInputStream ois) {
        this.create();
    }
}
我遇到的问题是spark为每一行调用
readObject
(每次调用
map()
中的函数时)。这是
RDD\map
的预期行为吗?如果可能的话,我希望每个节点只反序列化一次对象。

map()spark中的转换将针对文本文件/或源文件中的每一行执行。其他选项是使用mapPartition(),此转换将在每个分区中调用一次。此外,在您的特定情况下,您可以调用coalesce(num_of_partition)这将只创建您指定的这么多分区,在这一步之后,您可以考虑调用mapPartition()

希望有帮助:

mapPartition()的工作原理,请参见以下内容:


与MapReduce不同,spark Map不提供设置清理和映射阶段

您必须应用自定义逻辑来执行设置和清理

很少有逻辑(只是尝试模拟map Reduce的设置、映射和清理)

  • 进行一个try-catch循环,并在最后一个块中调用cleaup。Shutdown-hook也是实现该循环的一个替代方法
  • 在try catch中调用map
  • try-catch的第一行检查布尔初始化变量(最初设置为false),并调用setup方法和set 将此变量设置为true
  • 请在下面的地图任务中找到Spark写入Aerospike的示例。

    在Map任务内部,spark初始化aerosike客户端,对每个输入行执行一些操作。Map任务完成后关闭连接


    请注意,在Spark中,所有任务都是线程而不是进程,因此明智地使用静态变量。

    如果您使用Hadoop/EMR S3文件系统客户端,您将受益于FS实例的缓存&因此每个(URI、用户)只会获得一个FS实例(和AWS S3客户端)配对。这一点很关键,因为AWS库需要一个线程池才能正常工作:它不是一个低成本的对象实例

    我听说使用S3文件系统客户端时存在一些性能问题。特别是在下载大量较小的文件时。不过,我要试一试。对于较小的文件,通过GET打开它们所花费的时间是>读取时间。您也会收到类似于0.4c/get的账单,因此您不需要数千个小文件。最好将它们合并为可分区的文件格式。Hadoop har类似于可以处理的.tar文件,尽管我在Spark&S3中没有这样做