2017-02-10 89 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