将大RDD文件加载到内存中

时间:2015-04-07 17:06:31

标签: apache-spark rdd

val locations = filelines.map(line => line.split("\t")).map(t => (t(5).toLong, (t(2).toDouble, t(3).toDouble))).distinct().collect() 


val cartesienProduct=locations.cartesian(locations).map(t=> Edge(t._1._1,t._2._1,distanceAmongPoints(t._1._2._1,t._1._2._2,t._2._2._1,t._2._2._2)))

代码执行完全正常,直到这里,但当我尝试使用" cartesienProduct"它被卡住了,

val count =cartesienProduct.count() 

任何有效做到这一点的帮助都将受到高度赞赏。

1 个答案:

答案 0 :(得分:0)

首先,如果写成:

,则可以使地图转换更具可读性
locations.cartesian(locations).map { 
  case ((a1, (b1, c1)), (a2, (b2, c2)) => 
       Edge(a1, a2, distanceAmongPoints(b1,c1,b2,c2)))
}

目标似乎是计算所有对的两点之间的距离。笛卡儿会给这对两次,有效地计算两次相同的距离。

为避免这种情况,一种方法可能是广播所有点的副本,然后进行部分比较。

val points: // an array of points.

val pointsRDD = sc.parallelize(points.zipWithIndex)

val bPoints = sc.broadcast(points)

pointsRDD.map { case (point, index) => 
   (index + 1 until bPoints.value.size).map { i =>  
      distanceBetweenPoints(point, bPoints.value.get(i))
   }
}

如果点的大小为N,则将点0与(点-1到点-N-1),点-1与(点-2到点-N-1)等进行比较。