Apache Spark Shuffle写入但没有随机读取

时间:2017-03-01 08:51:18

标签: apache-spark apache-spark-mllib

再一次火花洗牌问题......

我在一个相当大的实例上设置了一个节点(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磁盘。我认为它正在完成这项工作,现在很好地使用了所有内核。好!

但是,我确实在执行程序选项卡中看到了一些我无法理解的内容:

Executor metrics screenshot

看起来只有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)
})

1 个答案:

答案 0 :(得分:1)

Shuffling意味着多个Spark阶段之间的数据交换。当在传输之前从所有执行器序列化所有数据时,在阶段结束时出现随机写入。随机读取发生在从所有执行者收集数据的阶段的开始。为了通过随机读/写获得整个画面,您必须以群集模式运行。在这种情况下,将触发随机读取和写入

修改

在您的情况下,您在一个实例中运行一个执行程序,这意味着不需要从其他执行程序带来分区,因此不会有随机读取。关于shuffle写入,它通过调用缓存在数据帧的保存操作期间出现。