从具有1个主服务器和2个工作服务器的集群执行Spark作业时可能出现序列化错

时间:2016-11-16 10:41:00

标签: scala apache-spark

我在群集上执行Spark作业。虽然它在本地模式下运行完美,但在集群中它在以下行中失败:

val labelsAndPredictions = testData.map(p => (model.predict(p.features), p.label))

我理解这个问题可能与工作人员无法访问对象model这一事实有关。因此我尝试了另一种方法。我创建了一个带有两个函数的可序列化对象Utils

object Utils {

  var model: GradientBoostedTreesModel = null

  def loadModel(m: GradientBoostedTreesModel): Unit = {
    model = m
  }

  def makePrediction(features: org.apache.spark.mllib.linalg.Vector): Double = {
    println(model.trees)
    val predictedLabel = model.predict(features)
    println("predictedLabel: " + predictedLabel)
    predictedLabel
  }

}

然后我将预测替换如下:

  model = GradientBoostedTrees.train(trainingData, boostingStrategy)
  Utils.loadModel(model)

  val labelsAndPredictions = testData.map { x =>
    val prediction = Utils.makePrediction(x.features)
    (x.label, prediction)
  }

这是我用来提交Spark作业的命令:

spark-submit --master yarn --deploy-mode cluster --driver-memory 10g --executor-memory 10g --num-executors 2 --conf "spark.executor.extraJavaOptions=-XX:+UseG1GC -XX:+AlwaysPreTouch" --class org.test.Runner s3://mybucket/keys/trainer.jar

1 个答案:

答案 0 :(得分:0)

utils对象无法解决问题,因为模型初始化为驱动程序而非工作者。

我最后一次检查(1.6.x)模型确实不可序列化。

你能做的是:

model.predict(testData.map(_.features))

但是这不会为你提供一个很好的方法来评估没有标签的模型。

或者

testData.toLocalIterator.map { x => (x.label, model.predict(x.features)) }

toLocalIterator迭代每个分区中的数据,但是在驱动程序而不是工作程序上,使您可以访问模型。不幸的是,没有并行化。