基于公共密钥合并两个RDD然后输出

时间:2015-07-08 18:28:32

标签: scala csv apache-spark

我对Scala和Spark以及一般的函数式编程都很陌生,所以如果这是一个非常基本的问题,请原谅我。

我正在合并两个CSV文件,因此我从中获得了很多灵感:Merge the intersection of two CSV files with Scala

虽然这只是Scala代码,我想在Spark中编写它来处理更大的CSV文件。

这部分代码我认为我是对的:

val csv1 = sc.textFile(Csv1Location).cache()
val csv2 = sc.textFile(Csv2Location).cache()

def GetInput1Key(input: String): Key = Key(getAtIndex(input.split(SplitByCommas, -1), Csv1KeyLocation))
def GetInput2Key(input: String): Key = Key(getAtIndex(input.split(SplitByCommas, -1), Csv2KeyLocation))

val intersectionOfKeys = csv1 map GetInput1Key intersection(csv2 map GetInput2Key)

val map1 = csv1 map (input => GetInput1Key(input) -> input)
val map2 = csv2 map (input => GetInput2Key(input) -> input)

val broadcastedIntersection = sc.broadcast(intersectionOfKeys.collect.toSet)

这就是我迷失的地方。我有两组密钥(intersectionOfKeys)存在于我的两个RDD中,我有两个包含[Key,String]映射的RDD。如果他们是普通地图,我可以这样做:

val output = broadcastedIntersection.value map (key => map1(key) + ", " + map2(key)) 

但该语法不起作用。

如果您需要有关CSV文件或我正在尝试完成的更多信息,请与我们联系。此外,如果你们都发现任何不正确的内容,我也会喜欢我的代码中的任何语法和/或惯用语。

更新

val csv1 = sc.textFile(Csv1Location).cache()
val csv2 = sc.textFile(Csv2Location).cache()

def GetInput1Key(input: String): Key = Key(getAtIndex(input.split(SplitByCommas, -1), Csv1KeyLocation))
def GetInput2Key(input: String): Key = Key(getAtIndex(input.split(SplitByCommas, -1), Csv2KeyLocation))

val intersectionOfKeys = csv1 map GetInput1Key intersection(csv2 map GetInput2Key)

val map1 = csv1 map (input => GetInput1Key(input) -> input)
val map2 = csv2 map (input => GetInput2Key(input) -> input)

val intersections = map1.join(map2)

intersections take NumOutputs foreach println

这段代码工作并做了我需要做的事情,但我想知道使用join是否有任何修改或性能影响。我记得在某处读取加入通常非常昂贵且耗时,因为所有数据都需要发送给所有分布式工作人员。

1 个答案:

答案 0 :(得分:2)

我认为hveiga是正确的,加入会更简单:

2 occurred 2 time
3 occurred 3 time
4 occurred 2 time
5 occurred 1 time
1 occurred 1 time

就我所见,这是更高性能和可读性,因为您需要在某些时候将两个集合加在一起,并且您的方式依赖于单个机器心态,您必须将每个集合拉入以确保您正在请求所有分区的行。请注意,我使用val csv1KV = csv1.map(line=>(GetInput1Key(line), line)) val csv2KV = csv2.map(line=>(GetInput2Key(line), line)) val joined = csv1KV join csv2KV joined.mapValues(lineTuple = lineTuple._1 + ", " lineTuple._2 ,这至少可以保持您的集合散列分区,并减少网络噪音。