Apache spark 在每次映射调用时触发反序列化对象
我试图创建一个spark RDD,每个文件一行,用于存储在s3中的一组文本文件。我通过创建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() {
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的设置、映射和清理)
请注意,在Spark中,所有任务都是线程而不是进程,因此明智地使用静态变量。如果您使用Hadoop/EMR S3文件系统客户端,您将受益于FS实例的缓存&因此每个(URI、用户)只会获得一个FS实例(和AWS S3客户端)配对。这一点很关键,因为AWS库需要一个线程池才能正常工作:它不是一个低成本的对象实例我听说使用S3文件系统客户端时存在一些性能问题。特别是在下载大量较小的文件时。不过,我要试一试。对于较小的文件,通过GET打开它们所花费的时间是>读取时间。您也会收到类似于0.4c/get的账单,因此您不需要数千个小文件。最好将它们合并为可分区的文件格式。Hadoop har类似于可以处理的.tar文件,尽管我在Spark&S3中没有这样做