[英]Spark Object (singleton) serialization on executors
我不确定我想要实现的目标是否可行。 我所知道的是,我正在从执行程序访问单例对象,以确保其构造函数在每个执行程序上仅被调用一次。 这种模式已经得到证明,并且可以在我的代码库中的类似用例中正常使用。
但是,我想知道的是,是否可以在驱动程序上将对象初始化后再运送对象。 在这种情况下,当访问ExecutorAccessedObject.y
,理想情况下,它不会调用println而是仅返回值。 这是一个高度简化的版本,实际上,我想在驱动程序上调用某些外部系统,因此在执行程序上访问时,它不会重新调用该外部系统。 我对@transient lazy val x
可以在执行程序上重新初始化一次没问题,因为它将保存一个无法序列化的连接池。
object ExecutorAccessedObject extends Serializable {
@transient lazy val x: Int = {
println("Ok with initialzing this on the executor. I.E. database connection pool")
1
}
val y: Int = {
// call some external system to return a value.
// I do not want to call the external system from the executor
println(
"""
|Idealy, this would not be printed on the executor.
|return value 1 without re initializing
""")
1
}
println("The constructor will be initialized Once on each executor")
}
someRdd.mapPartitions { part =>
ExecutorAccessedObject
ExecutorAccessedObject.x // first time accessed should re-evaluate
ExecutorAccessedObject.y // idealy, never re-evaluate and return 1
part
}
我也尝试使用广播变量来解决这个问题,但是我不确定如何在单例对象中访问广播变量。
我想知道的是,在驱动程序上初始化对象之后,是否可以运送该对象。
你不能。 作为单例的Objects
永远不会交付给执行者。 每当首次访问对象时,都会在本地进行初始化。
如果调用的结果是可序列化的,则只需将其单独传递,要么作为参数传递给ExecutorAccessedObject
(隐式或显式),要么使ExecutorAccessedObject
可变(并添加所需的同步)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.