Spark在每个地图调用上反序列化对象

时间:2017-10-30 17:13:59

标签: apache-spark

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

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();
    }
}

我遇到的问题是,每次调用readObject时,每次调用map()内的函数。这只是RDD#map的预期行为吗?如果可能,我希望每个节点只对对象进行一次反序列化。

3 个答案:

答案 0 :(得分:0)

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

希望有所帮助:

mapPartition()如何工作,见下文:

http://www.mishudi.com/general-spark-transformation/#mapPartitions

答案 1 :(得分:0)

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

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

很少有逻辑(只是试图模仿Map Reduce的设置,映射和清理)

  
      
  1. 尝试捕获循环并在最后一个块中调用cleaup。关闭钩也可以替代相同的
  2.   
  3. 在try catch
  4. 中进行地图调用   
  5. try catch的第一行检查boolean initialize变量(最初设置为false)并调用setup方法并设置   这个变量为真。
  6.   

请在Map任务中找到Spark写给Aerospike的示例。 http://bytepadding.com/big-data/spark/write-to-aerospike-from-spark/

Inside Map任务,spark初始化aerosike客户端,为每个输入行执行一些操作。在地图任务完成时关闭连接。

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

答案 2 :(得分:0)

如果您使用Hadoop / EMR S3文件系统客户端,您将获得FS实例缓存的好处。因此,每个(URI,用户)对只能获得一个FS实例(和AWS s3客户端)。这对AWS lib& amp;需要一个线程池才能正常工作:它不是一个低成本的对象实例