再一次火花洗牌问题......
我在一个相当大的实例上设置了一个节点(160GB RAM,40个内核)。我想用不同的参数(基于相同的数据帧)训练约250个ALS模型。
经过多天查看磁盘I / O问题后,我发现了以下对话:http://apache-spark-developers-list.1001551.n3.nabble.com/Eliminating-shuffle-write-and-spill-disk-IO-reads-writes-in-Spark-td16955.html
我确实喜欢他们说并将spark.local.dir
指向RAM磁盘。我认为它正在完成这项工作,现在很好地使用了所有内核。好!
但是,我确实在执行程序选项卡中看到了一些我无法理解的内容:
看起来只有Shuffle写作但没有阅读。简单的问题:为什么?有必要吗?如果没有:我怎么能避免这种情况?
执行的主要部分:
val modelsAndResults = parameters.par.map( e => {
var auc = 0d
splits.zipWithIndex.foreach { case ((training, validation), splitIndex) =>
val trainingDataset = spark.createDataFrame(training, schema).cache()
val validationDataset = spark.createDataFrame(validation, schema).cache()
val als = baseALS.copy(ParamMap(
baseALS.rank -> e._2,
baseALS.maxIter -> e._1,
baseALS.alpha -> e._4,
baseALS.regParam -> e._5,
baseALS.nonnegative -> e._6));
//println(s"$e evaluating $splitIndex ...")
val localAUC = new BinaryClassificationEvaluator().evaluate(
validationDataset
.join(als.fit(trainingDataset).transform(validationDataset.drop("time")), Seq("user","article"))
.withColumn("label", when($"time" >= e._2, 1d).otherwise(0d)).drop("time")
.withColumn("rawPrediction", $"prediction".cast(DoubleType))
.select("label","rawPrediction"))
auc += localAUC
trainingDataset.unpersist()
validationDataset.unpersist()
//println(s"$e evaluating $splitIndex ... localAUC: $localAUC")
}
val finalAUC = auc / splits.size
val csv = CSVWriter.open("cf_gridsearch_results_12345.csv", append = true)
csv.writeRow(List(e._1,e._2,e._3,e._4,e._5,e._6,finalAUC))
csv.close()
println((e._1,e._2,e._3,e._4,e._5,e._6,finalAUC))
(e._1,e._2,e._3,e._4,e._5,e._6,finalAUC)
})
答案 0 :(得分:1)
Shuffling意味着多个Spark阶段之间的数据交换。当在传输之前从所有执行器序列化所有数据时,在阶段结束时出现随机写入。随机读取发生在从所有执行者收集数据的阶段的开始。为了通过随机读/写获得整个画面,您必须以群集模式运行。在这种情况下,将触发随机读取和写入
修改强>
在您的情况下,您在一个实例中运行一个执行程序,这意味着不需要从其他执行程序带来分区,因此不会有随机读取。关于shuffle写入,它通过调用缓存在数据帧的保存操作期间出现。