在我的项目中,有一个应用程序向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是否支持从多个部分创建文件?
答案 0 :(得分:0)
您可以使用sparkContext.addFile()
。
根据Spark文档
在每个节点上添加要使用此Spark作业下载的文件。该 传递的路径可以是本地文件,HDFS中的文件(或其他文件) Hadoop支持的文件系统),或HTTP,HTTPS或FTP URI。访问 在Spark作业中的文件中,使用SparkFiles.get(fileName)来查找它 下载位置。如果递归选项是,则可以给出目录 设为true。目前仅支持目录 Hadoop支持的文件系统。
希望这有帮助。