我对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是否有任何修改或性能影响。我记得在某处读取加入通常非常昂贵且耗时,因为所有数据都需要发送给所有分布式工作人员。
答案 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
,这至少可以保持您的集合散列分区,并减少网络噪音。