为什么将 spark 中的参数提取到局部变量被认为更安全?
Why extracting an argument in spark to local variable is considered safer?
我在这本书上看到这个例子《学习Spark:闪电般快速的大数据分析》:
class SearchFunctions(val query: String) {
// more methods here
def getMatchesNoReference(rdd: RDD[String]): RDD[String] = {
// Safe: extract just the field we need into a local variable
val query_ = this.query
rdd.map(x => x.split(query_))
}
}
我的问题是 - 评论说:
安全:仅将我们需要的字段提取到局部变量中
为什么提取到局部变量比使用字段(定义为 val
)本身更安全?
因为当您仅提取时 query_
必须序列化并发送给工作人员。
如果您不提取,将发送 SearchFunctions
的完整实例。
Passing Functions in Spark 真的很有帮助,可以回答您的问题。
想法是您只希望将查询传达给需要它的工作人员,而不是整个对象(class)。
如果您没有那样做(如果您使用 map()
中的字段而不是局部变量),那么:
...sending the object that contains that class along with the method. In a similar way, accessing fields of the outer object will reference the whole object
请注意,这也更安全,不仅效率更高,因为它最大限度地减少了内存使用。
你看,当处理非常大的数据时,你的作业将面临内存限制,如果超过它们,它将被资源管理器(例如 YARN)杀死,所以我们要确保我们使用尽可能少的内存,以确保我们的工作能够完成而不是失败!
而且,对象越大,通信开销越大。 TCP 连接可能会被 peer 重置,当通信量太大时,这将调用不必要的开销,我们希望避免这种情况,因为通信不良也是作业失败的原因。
因为其他答案没有提到它:它更安全的另一个原因是因为 class 您引用的 fields/methods 可能无法序列化。由于 Java 不允许在编译时检查它,您将遇到运行时故障。 Whosebug上这类问题的例子非常多:我找到的前几个是Task not serializable: java.io.NotSerializableException when calling function outside closure only on classes not objects, , Enriching SparkContext without incurring in serialization issues, Spark serialization error。搜索 spark NotSerializableException
应该会给你更多,当然不仅仅是在 Stack Overflow 上。
或者它现在可能是可序列化的,但显然不相关的更改(例如添加您的 lambda 不使用的字段)可能会破坏您的代码,使其不可序列化或显着降低您的性能。
我在这本书上看到这个例子《学习Spark:闪电般快速的大数据分析》:
class SearchFunctions(val query: String) {
// more methods here
def getMatchesNoReference(rdd: RDD[String]): RDD[String] = {
// Safe: extract just the field we need into a local variable
val query_ = this.query
rdd.map(x => x.split(query_))
}
}
我的问题是 - 评论说: 安全:仅将我们需要的字段提取到局部变量中
为什么提取到局部变量比使用字段(定义为 val
)本身更安全?
因为当您仅提取时 query_
必须序列化并发送给工作人员。
如果您不提取,将发送 SearchFunctions
的完整实例。
Passing Functions in Spark 真的很有帮助,可以回答您的问题。
想法是您只希望将查询传达给需要它的工作人员,而不是整个对象(class)。
如果您没有那样做(如果您使用 map()
中的字段而不是局部变量),那么:
...sending the object that contains that class along with the method. In a similar way, accessing fields of the outer object will reference the whole object
请注意,这也更安全,不仅效率更高,因为它最大限度地减少了内存使用。
你看,当处理非常大的数据时,你的作业将面临内存限制,如果超过它们,它将被资源管理器(例如 YARN)杀死,所以我们要确保我们使用尽可能少的内存,以确保我们的工作能够完成而不是失败!
而且,对象越大,通信开销越大。 TCP 连接可能会被 peer 重置,当通信量太大时,这将调用不必要的开销,我们希望避免这种情况,因为通信不良也是作业失败的原因。
因为其他答案没有提到它:它更安全的另一个原因是因为 class 您引用的 fields/methods 可能无法序列化。由于 Java 不允许在编译时检查它,您将遇到运行时故障。 Whosebug上这类问题的例子非常多:我找到的前几个是Task not serializable: java.io.NotSerializableException when calling function outside closure only on classes not objects, spark NotSerializableException
应该会给你更多,当然不仅仅是在 Stack Overflow 上。
或者它现在可能是可序列化的,但显然不相关的更改(例如添加您的 lambda 不使用的字段)可能会破坏您的代码,使其不可序列化或显着降低您的性能。