使用火花键来优化笛卡尔积

时间:2016-07-30 17:31:02

标签: scala hadoop apache-spark

为了避免计算所有可能的组合,我试图根据某个键对值进行分组,然后计算每个键的值的笛卡尔乘积,即:

Input [(k1, v1), (k1, v2), (k2, v3)]

所需输出:[(v1, v1), (v1, v2), (v2, v2), (v2, v1), (v3, v3)]以下是我尝试执行的代码:

val input = sc.textFile('data.csv')
val rdd = input.map(s=>s.split(","))
               .map(s => (s(1).toString,  s(2).toString))
val group_result:RDD[String, Iterable[String]] = rdd.groupByKey()
group_result.flatMap { t =>
{
  val stream1= t._2.toStream
  val stream2= t._2.toStream

  stream1.flatMap { src =>
    stream2.par.map { trg =>
            src + "," + trg
    }
  }
}
}

这适用于非常小的文件,但是当列表(Iterable)的长度大约为1000时,计算完全冻结。

1 个答案:

答案 0 :(得分:0)

正如@ zero323所说,解决这个问题的最好方法是使用PairRDDFunctions的方法join,但是为了达到这个目的,你需要有PairedRDD,这可以通过使用RDD获得方法keyBy

您可以执行以下操作:

val rdd = sc.parallelize(Array(("k1", "v1"), ("k1", "v2"), ("k2", "v3"))).keyBy(_._1)

val result = rdd.join(rdd).map{
  case (key: String, (x: Tuple2[String, String], y: Tuple2[String, String])) => (x._2, y._2)
}

result.take(20)
// res9: Array[(String, String)] = Array((v1,v1), (v1,v2), (v2,v1), (v2,v2), (v3, v3))

Here我与代码共享笔记本。