Spark 作业中的 Scala 成员字段可见性
Scala member field visibility in Spark jobs
我有一个 Scala class,我这样定义:
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)
我需要了解什么,关于字段和范围界定和可见性以及火花提交和对象和单例等等,以理解为什么会发生这种情况?如果我基本上希望定义为 "constants" 的变量对 getData
方法可见,我应该怎么做?
想通了。这是造成麻烦的 App
特征。它甚至体现在这个简单的 class:
object TestObject extends App {
val FAMILY = "data"
override def main(args: Array[String]) = println(FAMILY, "data")
}
# prints "(null,data)"
貌似App
inherits from DelayedInit
,也就是说main()
运行的时候,FAMILY
还没有初始化。正是我不想要的,所以我将停止使用 App
。
我可能遗漏了一些东西,但我认为您不应该定义 main
方法。当您扩展 App
、you inherit a main
时,您不应该覆盖它,因为那是实际调用 App
.
中的代码的地方
比如你答案中简单的class应该写成
object TestObject extends App {
val FAMILY = "data"
println(FAMILY, "data")
}
我有一个 Scala class,我这样定义:
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)
我需要了解什么,关于字段和范围界定和可见性以及火花提交和对象和单例等等,以理解为什么会发生这种情况?如果我基本上希望定义为 "constants" 的变量对 getData
方法可见,我应该怎么做?
想通了。这是造成麻烦的 App
特征。它甚至体现在这个简单的 class:
object TestObject extends App {
val FAMILY = "data"
override def main(args: Array[String]) = println(FAMILY, "data")
}
# prints "(null,data)"
貌似App
inherits from DelayedInit
,也就是说main()
运行的时候,FAMILY
还没有初始化。正是我不想要的,所以我将停止使用 App
。
我可能遗漏了一些东西,但我认为您不应该定义 main
方法。当您扩展 App
、you inherit a main
时,您不应该覆盖它,因为那是实际调用 App
.
比如你答案中简单的class应该写成
object TestObject extends App {
val FAMILY = "data"
println(FAMILY, "data")
}