spark:在另一个rdd内访问rdd

时间:2017-05-15 10:49:20

标签: scala apache-spark apache-spark-sql spark-dataframe

我有一个大小为6000的查找rdd,lookup_rdd:RDD [String]

a1 a2 a3 a4 a5 .....

和另一个rdd,data_rdd:RDD [(String,Iterable [(String,Int)])] :( id,(item,count)),它有唯一的ID,

(id1,List((a1,2), (a3,4))) (id2,List((a2,1), (a4,2), (a1,1))) (id3,List((a5,1)))

lookup_rdd中的FOREACH元素我想检查每个id是否具有该元素,如果它在那里我放了计数,如果它不是我放0,并存储在文件中。

实现这一目标的有效方法是什么?哈希可能吗?例如。我想要的输出是:

id1,2,0,4,0,0 id2,1,1,0,2,0 id3,0,0,0,0,1

我试过这个:

val headers = lookup_rdd.zipWithIndex().persist()  
val indexing = data_rdd.map{line =>
  val id = line._1
  val item_cnt_list = line._2
  val arr = Array.fill[Byte](6000)(0)
  item_cnt_list.map(c=>(headers.lookup(c._1),c._2))
  }
indexing.collect().foreach(println)

我得到例外:

org.apache.spark.SparkException: RDD transformations and actions can only be invoked by the driver, not inside of other transformations

1 个答案:

答案 0 :(得分:2)

坏消息是你不能在另一个中使用RDD。

好消息是,对于您的用例,假设6000个条目相当小,有一个理想的解决方案:在驱动程序上收集RDD,将其广播回集群的每个节点并在另一个节点内使用它RDD就像你之前做的那样。

val sc: SparkContext = ???
val headers = sc.broadcast(lookup_rdd.zipWithIndex.collect().toMap)
val indexing = data_rdd.map { case (_, item_cnt_list ) =>
  item_cnt_list.map { case (k, v) => (headers.value(k), v) }
}
indexing.collect().foreach(println)