[英]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.