使用Apache Spark写入HDFS时的输出序列

时间:2016-02-25 16:22:25

标签: scala hadoop apache-spark rdd

我正在使用apache Spark开发一个项目,并且需要将spark的已处理输出写入Header -> Data -> Trailer这样的特定格式。为了写入HDFS,我使用.saveAsHadoopFile方法,并使用密钥作为文件名将数据写入多个文件。但问题是数据序列不是维护文件是用Data->Header->Trailer或三者的不同组合写的。 RDD转换中有什么我缺少的吗?

1 个答案:

答案 0 :(得分:1)

好的,所以从谷歌阅读StackOverflow问题,博客和邮件档案。我发现了.union()和其他转换的确切运作方式以及如何管理分区。当我们使用.union()时,生成的RDD会丢失分区信息,也会导致排序,以及为什么我的输出序列没有得到维护。

我为克服这个问题所做的是将记录编号为

Header = 1,Body = 2,Footer = 3

所以在RDD上使用sortBy这是所有三个的联合我使用这个订单号和1个分区对它进行了排序。然后使用密钥作为文件名写入多个文件我使用HashPartitioner,以便相同的密钥数据应该进入单独的文件。

val header: RDD[(String,(String,Int))] = ... // this is my header RDD`
val data: RDD[(String,(String,Int))] = ... // this is my data RDD
val footer: RDD[(String,(String,Int))] = ... // this is my footer RDD

val finalRDD: [(String,String)] = header.union(data).union(footer).sortBy(x=>x._2._2,true,1).map(x => (x._1,x._2._1))

val output: RDD[(String,String)] = new PairRDDFunctions[String,String](finalRDD).partitionBy(new HashPartitioner(num))

output.saveAsHadoopFile    ... // and using MultipleTextOutputFormat save to multiple file using key as filename

这可能不是最终或最经济的解决方案,但它有效。我还试图找到其他方法来保持输出序列为Header->Body->Footer。我还在所有三个RDD上尝试了.coalesce(1),然后进行了联合,但这只是向RDD添加了三个转换,而.sortBy函数也获取了我认为会有的分区信息相同,但首先合并RDD也是有效的。如果任何人有其他方法,请让我知道,或添加更多这将是非常有帮助的,因为我是Spark的新手

参考文献:

Write to multiple outputs by key Spark - one Spark job

Ordered union on spark RDDs

http://apache-spark-user-list.1001560.n3.nabble.com/Union-of-2-RDD-s-only-returns-the-first-one-td766.html - 这个有很多帮助