2017-02-10 90 views
0

我在Spark中獲得了簡單的getter方法的意外行爲。Spark的方法關閉

1)我有一個抽象類,有一個變量和它的getter。

abstract class SparkApp { 
    private var _date: String = _ 
    def getDate: String = _date 

    def run(): Unit 

    def main(args: Array[String]): Unit = { 
     _date: String = "2017-02-10" 
     run() 
    } 
} 

2)擴展SparkApp做RDD轉換。

object MySparkApp extends SparkApp { 
    override def run(): Unit = { 
     rdd.map { each => 
     // Call parent's method 
     // getDate returns null, _date has value though. 
     getDate.replace("-", "/") 
     } 
    } 
} 

在簇3)運行MySparkApp,然後getDate返回NULL。
4)但是,如果直接調用_date,則按預期工作。

所以我的問題是,這兩者有什麼區別?
我通過Spark docs的Passing Functions to Spark看過,但沒有任何提示。

提前致謝!

+0

這裏沒有足夠的能夠告訴你問題是什麼。請創建一個[最小化,完整和可驗證的示例](http://stackoverflow.com/help/mcve),以說明您的問題。 –

+0

@JoeC明白了。我修改了上面的代碼。 – NaHeon

回答

1

當您直接撥打_date時,您會在驅動程序中獲取_date的值,因爲它在閉包中被捕獲並序列化併發送給執行程序。當您使用getDate方法時,您只需在執行程序上調用該方法,該程序將在執行程序上返回_date的值,因爲您從不初始化該程序,因此該程序爲null

將日期作爲參數傳遞給run可能是在超類中有一個字段的更好的解決方案,因爲它使得它更明顯地發生了什麼。

+0

您的答案接受我首先想到的是,'getDate'方法引用'_date',以便'_date'的初始化值也在閉包中捕獲,但它看起來像一個引用值是指執行者內部的值。 – NaHeon

0

我不是100%肯定你有什麼做的,但是,如果我理解正確的執行,你的解決方案將更換:

getDate.replace("-", "/") 

each.getDate.replace("-", "/") 
+0

原始代碼的意思是使用外部方法,來自其父類。 – NaHeon

+0

這種情況不同。 ''{方法(以及其他spark轉換)的主體將在'executor'上執行(可能是一個完全不同的機器,所以'master'和'executors'上'MySparkApp'的狀態會有所不同,因爲'_date:String =「2017-02-10」'只在'master'上完成 – semsorock

+0

如果是這樣,看起來像在執行程序中調用'_date'也可以返回null,不是嗎?但它不是並使用變量解決問題 – NaHeon