繁体   English   中英

Spark作业中的Scala成员字段可见性

[英]Scala member field visibility in Spark jobs

我有一个这样定义的Scala类:

import org.apache.spark.{SparkConf, SparkContext}

object TestObject extends App{
  val FAMILY = "data".toUpperCase

  override def main(args: Array[String]) {
    val sc = new SparkContext(new SparkConf())

    sc.parallelize(1 to 10)
      .map(getData)
      .saveAsTextFile("my_output")
  }

  def getData(i: Int) = {
    ( i, FAMILY, "data".toUpperCase )
  }
}

我将其提交给YARN集群,如下所示:

HADOOP_CONF_DIR=/etc/hadoop/conf spark-submit \
    --conf spark.hadoop.validateOutputSpecs=false \
    --conf spark.yarn.jar=hdfs:/apps/local/spark-assembly-1.2.1-hadoop2.4.0.jar \
    --deploy-mode=cluster \
    --master=yarn \
    --class=TestObject \
    target/scala-2.11/myjar-assembly-1.1.jar

出乎意料的是,输出如下所示,指示getData方法看不到FAMILY的值:

(1,null,DATA)
(2,null,DATA)
(3,null,DATA)
(4,null,DATA)
(5,null,DATA)
(6,null,DATA)
(7,null,DATA)
(8,null,DATA)
(9,null,DATA)
(10,null,DATA)

关于字段,作用域和可见性以及火花提交,对象和单例以及诸如此类的东西,我需要了解什么才能理解为什么会这样? 如果我基本上希望将变量定义为getData方法可见的“常量”,那我应该怎么做呢?

我可能会丢失一些东西,但是我不认为您应该定义一个main方法。 扩展App您继承了main ,因此不应覆盖它,因为那实际上是在App调用代码的原因。

例如,答案中的简单类应写成

object TestObject extends App {
  val FAMILY = "data"
  println(FAMILY, "data")
}

弄清楚了。 这是造成麻烦的App特性。 即使在这个简单的类中也能体现出来:

object TestObject extends App {
  val FAMILY = "data"
  override def main(args: Array[String]) = println(FAMILY, "data")
}
# prints "(null,data)"

显然, App 继承自DelayedInit ,这意味着在运行main() ,尚未初始化FAMILY 正是我所不想要的,所以我将停止使用App

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM