Performance Spark性能-如何并行化大型循环?

Performance Spark性能-如何并行化大型循环?,performance,scala,parallel-processing,apache-spark,Performance,Scala,Parallel Processing,Apache Spark,我有一个Spark应用程序,总共包含8000个循环,它在5个节点的集群上运行。每个节点有125GB内存和32个核心。相关代码如下所示: for (m <- 0 until deviceArray.size) { // there are 1000 device var id = deviceArray(m) for (t <- 1 to timePatterns) { // there are 8 time patterns var hrpvData = get

我有一个Spark应用程序,总共包含8000个循环,它在5个节点的集群上运行。每个节点有125GB内存和32个核心。相关代码如下所示:

for (m <- 0 until deviceArray.size) { // there are 1000 device 
  var id = deviceArray(m)

  for (t <- 1 to timePatterns) { // there are 8 time patterns
     var hrpvData = get24HoursPVF(dataDF, id, t).cache()

  var hrpvDataZI = hrpvData.zipWithIndex

  var clustersLSD = runKMeans(hrpvData, numClusters, numIterations)

  var clusterPVPred = hrpvData.map(x => clustersLSD.predict(x))
  var clusterPVMap = hrpvDataZI.zip(clusterPVPred)

  var pvhgmRDD = clusterPVMap.map{r => (r._2, r._1._2)}.groupByKey

  var arrHGinfo = pvhgmRDD.collect 

  // Post process data 
  // .....

  hrpvData.unpersist()
  }
}
for(m(r.\u 2,r.\u 1.\u 2)}.groupByKey
var arrHGinfo=pvhgmRDD.collect
//后处理数据
// .....
hrpvData.unpersist()
}
}
函数调用
get24HoursPVF()
为k-means准备特征向量,大约需要40秒。每个循环大约需要50秒才能完成集群的使用。我的数据大小为2到3 GB(从表中读取)。如果循环次数为8000次,则运行此Spark应用程序的总时间是不可接受的(8000x50秒)


由于每个设备都是独立的,有没有办法并行8000次迭代?或者如何利用集群来解决总运行时间过长的问题?Scala Future不会工作,因为它几乎同时提交作业,但Spark不会同时运行这些作业。

除了for循环之外,还有两个最慢的PI在您的代码中调用Spark-
groupByKey
,以及
collect

groupByKey几乎不应该被使用,相反,请查看
reduceByKey
,更多详细信息请参见此

collect
将该RDD中的所有数据传输到驱动程序节点上的一个数组,除非数据量很小,否则会对性能产生相当大的影响

在for循环中,我不太熟悉您试图做什么,但是

var hrpvData = get24HoursPVF(dataDF, id, t).cache()

您正在为每个id和t值构建和缓存一个新的数据帧。我不知道为什么您不能在一开始构建一个包含每个id和t变量的数据帧,然后在整个数据帧上运行zipWithIndex、map等?

谢谢您的评论。我同意groupByKey应该被reduceByKey取代,但在这个c中与其他耗时部分相比,groupByKey上的时间可以忽略。Collect()在此传输少量数据。我需要在每个设备上以每个时间模式运行k-means群集,这就是我认为必须为每个id和t(以及特征向量)构建和缓存新数据帧的原因.你的评论让我再次思考为什么我不能构建一个大数据帧。实际上我可以。至少通过这种方式,我可以移动函数调用get24HoursPVF()在8000个循环之外,虽然我仍然需要运行k-means集群8000次。因此它将缩短运行时间。再次感谢!准确地说,
groupByKey
并不比任何需要洗牌类似数量数据的操作更昂贵。这意味着遵循此逻辑,您应该避免
join
coogroup
partitionBy
或任何类似的方法。除了join、cogroup等有很大的区别外,没有简单的无乱序选项。如果需要group和not group,然后进行一些缩减,那么groupBy key也没有其他选择。如果你是说REDUCTEBYKEY,就不要使用groupByKey,而不是避免groupByKey。groupByKey也没有ave没有洗牌选项-它只有-ess洗牌选项。