Apache Spark - Scala - ReduceByKey - 键只重复两次

时间:2016-08-08 12:20:33

标签: scala apache-spark

鉴于以下RDD:

val vectors = RDD [String, Int] = ((k1,v1),(k1,v2),(k2,v3),...)

其中键出现两次(k1)或一次(k2),但不会超过。我想得到:

val uniqVectors = RDD[String, Int] = ((k1, v1*v2), (k2, v3), ...)

一种方法是使用reduceByKey:

val uniqVectors = vectors.reduceByKey((a,b) => a*b)

但是,对于具有7B元素的数组来说,它太慢了。 在这个具体案例中有没有更快的方法?

1 个答案:

答案 0 :(得分:0)

这里花费时间(可能)正在改变数据:当你想要将两个或多个记录组合在一起时,它们必须位于同一个分区中,因此Spark必须首先 shuffle 记录这样所有具有相同密钥的记录都在一个分区中。

现在,即使每个密钥最多有两个记录,也必须进行此随机播放,除非您能以某种方式保证每个密钥已包含在单个分区中 - 例如,如果你从HDFS加载这个RDD,你知道每个键都在一个文件部分开始。在那种(不太可能)的情况下,您可以使用mapPartitions分别在每个分区上自行执行分组,从而节省随机播放:

vectors.mapPartitions( 
  iter => iter.toList.groupBy(_._1).map { case (k, list) => (k, list.map(_._2).reduce(_ * _)) }.iterator, 
  preservesPartitioning = true)

顺便说一下,对于每个键的最大重复次数为2的情况,这一点都不是特别的。