我不確定我想實現的是否可能。我所知道的是,我正從一個執行器訪問單例對象,以確保它的構造器在每個執行器上只被調用一次。這種模式已經在我的代碼庫中被證明和按照預期用於類似的用例。執行者上的Spark對象(單例)序列化
但是,我想知道的是,如果我可以在驅動程序初始化之後運送對象。在這種情況下, 訪問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
}
我試圖用廣播變量解決這個問題,但我不確定如何訪問單例對象內的廣播變量。
謝謝你的回答。當你說明確地將參數傳遞給對象時,你的意思是使它成爲一個帶有參數的類? –
我寧願考慮參數化方法調用。使用類而不是對象應該也可以。 – user8925690