Spark有個關于是否允許一個application存在多個SparkContext實體的配置項, 如下:
spark.driver.allowMultipleContexts: If true, log warnings instead of throwing exceptions when multiple SparkContexts are active.
該值默認為false, 即不允許一個application同時存在一個以上的active SparkContext實體. 如何保證這一點呢?
在SparkContext建構式最開始處獲取是否允許存在多個SparkContext實體的標識allowMultipleContexts, 我們這里只討論否的情況 ( 默認也是否, 即allowMultipleContexts為false )
class SparkContext(config: SparkConf) extends Logging with ExecutorAllocationClient {
//< 如果為true,有多個SparkContext處于active狀態時記錄warning日志而不是拋出例外.
private val allowMultipleContexts: Boolean =
config.getBoolean("spark.driver.allowMultipleContexts", false)
//< 此處省略n行代碼
}
//< 注意: 這必須放在SparkContext構造器的最開始
SparkContext.markPartiallyConstructed(this, allowMultipleContexts)
private[spark] def markPartiallyConstructed(
sc: SparkContext,
allowMultipleContexts: Boolean): Unit = {
SPARK_CONTEXT_CONSTRUCTOR_LOCK.synchronized {
assertNoOtherContextIsRunning(sc, allowMultipleContexts)
contextBeingConstructed = Some(sc)
}
}
//< 伴生物件SparkContext包含一組實用的轉換和引數來和各種Spark特性一起使用
object SparkContext extends Logging {
private val SPARK_CONTEXT_CONSTRUCTOR_LOCK = new Object()
//< 此處省略n行代碼
}
結合以上三段代碼, 可以看出保證一個Spark Application只有一個SparkContext實體的步驟如下:
-
通過SparkContext伴生物件object SparkContext中維護了一個物件
SPARK_CONTEXT_CONSTRUCTOR_LOCK, 單例SparkContext在一個行程中是唯一的, 所以SPARK_CONTEXT_CONSTRUCTOR_LOCK在一個行程中也是唯一的 -
函式markPartiallyConstructed中通過synchronized方法保證同一時間只有一個執行緒能處理
assertNoOtherContextIsRunning(sc, allowMultipleContexts)
contextBeingConstructed = Some(sc)assertNoOtherContextIsRunning會檢測是否有其他SparkContext物件正在被構造或已經構造完成, 若allowMultipleContexts為true且確有正在或者已經完成構造的SparkContext物件, 則拋出例外, 否則完成SparkContext物件構造
看到這里, 有人可能會有疑問, 這雖然能保證在一個行程內只有唯一的SparkContext物件, 但Spark是分布式的, 是不是無法保證在在其他節點的行程內會構造SparkContext物件. 其實并不存在這樣的問題, 因為SparkContext只會在Driver中得main函式中宣告并初始化, 也就是說只會在Driver所在節點的一個行程內構造.
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/1093.html
標籤:大數據
下一篇:滴滴七層接入平臺實踐和探索
