将Array [(String,String)]类型转换为spark中的RDD [(String,String)]类型

时间:2016-09-21 11:48:59

标签: scala apache-spark

我是新来的。

这是我的代码:

val Data = sc.parallelize(List(
      ("I", "India"), 
      ("U", "USA"), 
      ("W", "West"))) 

val DataArray = sc.broadcast(Data.collect)

val FinalData = DataArray.value

此处FinalData属于Array[(String, String)]类型。 但我希望数据采用RDD[(String, String)]类型的形式。

我可以将FinalData转换为RDD[(String, String)]类型。

更多细节:

我想加入两个RDD所以优化连接条件(从性能的角度来看) 我正在向所有集群广播小型RDD,以便数据改组更少。(间接性能将得到改善) 所以对于这一切,我写的是这样的:

//Big Data
val FirstRDD = sc.parallelize(List(****Data of first table****))

//Small Data
val SecondRDD = sc.parallelize(List(****Data of Second table****)) 

如此彻底地我会播放小数据集(意味着SecondRDD)

val DataArray = sc.broadcast(SecondRDD.collect)

val FinalData = DataArray.value

//这里会给出错误

val Join = FirstRDD.leftOuterJoin(FinalData)
  

找到阵列需要RDD

这就是我正在寻找Array to RDD转换的原因。

2 个答案:

答案 0 :(得分:3)

真正的问题是,您正在通过收集Broadcast来创建RDD变量(请注意,此操作会将RDD转换为Array)。所以,我所说的是你已经有一个RDD Data,而且这个变量的值与FinalData完全相同,但是你想要的形式是RDD[(String, String)] 1}}。

您可以在以下输出中查看此内容。

Data: org.apache.spark.rdd.RDD[(String, String)] = ParallelCollectionRDD[2] at parallelize at <console>:32
DataArray: org.apache.spark.broadcast.Broadcast[Array[(String, String)]] = Broadcast(1)
FinalData: Array[(String, String)] = Array((I,India), (U,USA), (W,West))

虽然,我不明白你的方法你只需要并行化Broadcast的值。

// You already have this data stored in `Data`, so it's useless repeat this process.
val DataCopy = sc.parallelize(DataArray.value)

修改

再次阅读你的问题后,我相信问题几乎是一样的。您正尝试使用join RDD Broadcast,而且不允许RDD。但是,如果您阅读文档,您可能会注意到join两个val joinRDD = FirstRDD.keyBy(_._1).join(SecondRDD.keyBy(_._1)) 都可能(请参阅下面的代码)。

$user

答案 1 :(得分:0)

广播对于提高大型RDD和较小型RDD之间的JOIN性能确实很有用。当您这样做时,广播(以及mapmapPartitions替换加入,它未在 加入中使用,因此,您绝不需要&#34; 将广播转换为RDD &#34;。

以下是它的外观:

val largeRDD = sc.parallelize(List(
  ("I", "India"),
  ("U", "USA"),
  ("W", "West")))

val smallRDD = sc.parallelize(List(
  ("I", 34),
  ("U", 45)))

val smaller = sc.broadcast(smallRDD.collectAsMap())

// using "smaller.value" inside the function passed to RDD.map ->
// on executor side. Broadcast made sure it's copied to each executor (once!)
val joinResult = largeRDD.map { case (k, v) => (k, v, smaller.value.get(k)) }

joinResult.foreach(println)
// prints:
// (I,India,Some(34))
// (W,West,None)
// (U,USA,Some(45))

查看类似的解决方案(使用mapPartitions)可能更有效here

相关问题