Apache Spark:RDD多次传递,操作简单

时间:2017-07-27 10:09:51

标签: scala apache-spark functional-programming rdd set-intersection

我遇到过这个问题,因为我正在学习Apache Spark框架。 考虑以下简单的RDD

scala> val rdd1 = sc.parallelize(List((1, Set("C3", "C2")), 
                                      (2, Set("C1", "C5", "C3")), 
                                      (3, Set("C2", "C7"))))
rdd1: RDD[(Int, Set[String])]

我希望将rdd1中每个元素中的每个元素与“#34;相同”中的每个元素的集合相交。 rdd1;所以结果将是以下形式:

newRDD: RDD[(Int, Int, Set[String])]
// and newRDD.collect will look like:
newRDD: Array[(Int, Int, Set[String])] = Array((1, 1, Set("C3", "C2")), (1, 2, Set("C3")), (1, 3, Set("C2")),
                                               (2, 1, Set("C3")), (2, 2, Set("C1", "C5", "C3")), (2, 3, Set()),
                                               (3, 1, Set("C2")), (3, 2, Set()), (1, 3, Set("C2", "C7")))

我尝试嵌套rdd1就像这样

scala> val newRDD = rdd1 map (x => {rdd1 map (y => (x._1, y._1, x._2.intersect(y._2)))})
然而,这将导致“任务不可邮寄”#39;例外。

现在,如果我想在执行

之前避免rdd1.collect()或任何其他操作操作
scala> val newRDD = rdd1 map (x => {rdd1 map (y => (x._1, y._1, x._2.intersect(y._2)))})

是否可以获得所需的newRDD

1 个答案:

答案 0 :(得分:4)

你得到的任务是不可服用的'异常是因为您尝试将RDD放入其他RDD的地图中,在这种情况下,Spark会尝试序列化第二个RDD。通常这种问题是你用连接解决的:

val newRDD = rdd1.cartesian(rdd1).map { case ((a, aSet), (b, bSet)) =>
   (a, b, aSet.intersect(bSet))
}

这里,笛卡尔联接在新的RDD中创建一对可以交叉的每一组。