我很好奇在Spark中将RDD传递给函数究竟是什么。
def my_func(x : RDD[String]) : RDD[String] = {
do_something_here
}
假设我们定义了一个如上所述的函数。当我们调用函数并传递一个现有的RDD [String]对象作为输入参数时,这个my_function是否会复制"复制"这个RDD作为函数参数?换句话说,它是通过引用调用还是按值调用?
答案 0 :(得分:12)
在Scala中传递任何东西都没有被复制(在C / C ++中你传递的值)。大多数基本类型Int,String,Double等都是不可变的,因此通过引用传递它们是非常安全的。 (注意:如果您正在传递一个可变对象而您进行了更改,那么任何引用该对象的人都会看到更改)。
最重要的是,RDD是惰性,分布式,不可变的集合。通过函数传递RDD并将transformation应用于它们(映射,过滤等)并不真正传输任何数据或触发任何计算。
所有链式转换都会被“记住”,并且当您在RDD上强制执行action时会自动触发,例如保留它,或者在驱动程序中本地收集它(通过{{1} },collect()
等。)
答案 1 :(得分:4)
Spark实现了“将代码发送到数据”的原则,而不是将数据发送到代码。所以这里恰好相反。它是将被分发并发送到RDD的功能。
RDD是不可变的,因此您的函数将创建一个新的RDD作为结果(转换)或创建一些值(动作)。
这里有趣的问题是,如果你定义一个函数,究竟是什么发送到RDD(并分配到不同的节点,其传输成本)?这里有一个很好的解释:
http://spark.apache.org/docs/latest/programming-guide.html#passing-functions-to-spark