每列Spark Streaming的高效countByValue

时间:2015-05-28 21:16:04

标签: scala apache-spark spark-streaming

我想在我的数据中找到每列的countByValues。我可以在基本批处理RDD中为每列(例如现在的2列)找到countByValue()作为休耕:

scala> val double = sc.textFile("double.csv") 
scala> val counts = sc.parallelize((0 to 1).map(index => {
     double.map(x=> { val token = x.split(",")
     (math.round(token(index).toDouble))
     }).countByValue()
     }))
scala> counts.take(2)
res20: Array[scala.collection.Map[Long,Long]] = Array(Map(2 -> 5, 1 -> 5), Map(4 -> 5, 5 -> 5))

现在我想对DStreams执行相同的操作。我有windowedDStream并想在每列上countByValue。我的数据有50列。我已经把它做成了休闲:

val windowedDStream = myDStream.window(Seconds(2), Seconds(2)).cache()  
ssc.sparkContext.parallelize((0 to 49).map(index=> {
val counts = windowedDStream.map(x=> { val token = x.split(",")
                                (math.round(token(index).toDouble))
                                }).countByValue()
counts.print()                                          
}))                                                
val topCounts = counts.map . . . .  will not work

我得到了正确的结果,唯一的问题是我想在计数上应用更多的操作,而且在地图之外它不可用。

1 个答案:

答案 0 :(得分:2)

你误解了parallelize的作用。你认为当你给它一个Seq的两个元素时,这两个元素将并行计算。事实并非如此,事实并非如此。

parallelize实际上做的是它从你提供的Seq创建一个RDD。

为了尝试阐明这一点,请考虑以下事项:

val countsRDD = sc.parallelize((0 to 1).map { index =>
  double.map { x =>
    val token = x.split(",")
    math.round(token(index).toDouble)
  }.countByValue()
})

等于:

val counts = (0 to 1).map { index =>
  double.map { x =>
    val token = x.split(",")
    math.round(token(index).toDouble)
  }.countByValue()
}
val countsRDD = sc.parallelize(counts)

parallelize运行时,工作已经完成。 parallelize无法追溯使用,以便计算并行发生。

问题的解决方案是不使用parallelize。这完全没有意义。