2015-03-18 23 views
0

我有定義,就像這樣的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) 
    } 
} 

我提交給紗線集羣,像這樣:

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方法?

+2

這是一個序列化的問題,它看起來像你正在使用KRYO序列化。你是否提供了正確的班級註冊?你有沒有嘗試刪除'spark.serializer = org.apache.spark.serializer.KryoSerializer'行? – maasg 2015-03-18 23:09:03

+0

如果我不在RDD中使用自定義類型,是否需要任何Kryo註冊? – 2015-03-19 14:16:31

+0

我已經從作業提交中刪除了Kryo行,同樣的問題仍然存在。 – 2015-03-23 18:37:13

回答

3

我可能會錯過一些東西,但我認爲您不應該定義main方法。當你擴展App,you inherit a main時,你不應該覆蓋它,因爲這實際上是調用你的App中的代碼。

例如,在你的答案簡單的類應該寫成

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

想通了。這是造成麻煩的App特質。它體現即使在這種簡單的類:

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

顯然Appinherits from DelayedInit,這意味着當main()運行,FAMILY尚未初始化。正是我不想要的,所以我要停止使用App

+2

肯,我認爲你誤解了App的工作方式。你不擴展應用程序,也定義一個主要;你擴展App *來代替*定義一個main。當你擴展App時,你*繼承* main,並且main調用你的App中的代碼,這是編譯器保存的一個函數。 – AmigoNico 2015-05-14 17:33:06

+0

你說得對。這似乎避免了初始化時間問題,我會接受你的答案。 – 2015-05-14 17:37:05