使用Spark下载分发的文件并上传到S3

时间:2017-11-08 07:55:38

标签: scala apache-spark amazon-s3

在我的项目中,有一个应用程序向Kafka发送多个BlogPost信息,每个博客帖子都包含许多媒体文件链接。我想编写一个使用Apache Spark来使用该Kafka流并以分布式方式下载所有媒体文件链接的应用程序。每个文件链接都将下载到许多分区中,它们将被合并并保存到S3存储中的单个文件中。

发送给Kafka的数据将具有以下结构:

class BlogPost {
   id: Long,
   links: List[String]
}

以下是我打算申请新Spark应用程序的主要实现:

// Create kafka direct stream
val sparkConf = new SparkConf()
val ssc = new StreamingContext(sparkConf)
val sc = ssc.sparkContext
val stream = KafkaUtils.createDirectStream[String, Array[Byte], StringDecoder, DefaultDecoder]
(ssc, kafkaParams, kafkaTopics)

// Process Kafka Stream
stream.foreachRDD { rdd =>  

    rdd.foreachPartition (p : BlogPost => {
        p.links.foreach(url => {
            // For each link post we download into multiple parts
            // and save them into single file in S3 storage
            val size = getContentLength(url)
            // Create partitions
            val partitions = partition( size )
            // Start to download partition and persist them into single file in S3          
            sc.parallelize( partitions, partitions.size )
                .map( partition => (partition, downloadPart( partition )) )
                .saveFile("s3://....")
        })      
    }
}

// Compute and create spark partitions
def partition( size: Long ): ArrayBuffer[Partition] =
{[...]}

// Download file part
def downloadPart( partition: Partition ): Array[Byte] =
{[...]}

我不知道这种方法是否正确。任何人都可以帮我解决这个问题或建议我更好的解决方案。 S3是否支持从多个部分创建文件?

1 个答案:

答案 0 :(得分:0)

您可以使用sparkContext.addFile()

根据Spark文档

  

在每个节点上添加要使用此Spark作业下载的文件。该   传递的路径可以是本地文件,HDFS中的文件(或其他文件)   Hadoop支持的文件系统),或HTTP,HTTPS或FTP URI。访问   在Spark作业中的文件中,使用SparkFiles.get(fileName)来查找它   下载位置。如果递归选项是,则可以给出目录   设为true。目前仅支持目录   Hadoop支持的文件系统。

希望这有帮助。