美文网首页Spark在简书大数据时代各种涨姿势大数据
如何保证一个Spark Application只有一个Spark

如何保证一个Spark Application只有一个Spark

作者: 牛肉圆粉不加葱 | 来源:发表于2015-06-23 23:17 被阅读4174次

    Spark有个关于是否允许一个application存在多个SparkContext实例的配置项, 如下:

    **spark.driver.allowMultipleContexts: ** If true, log warnings instead of throwing exceptions when multiple SparkContexts are active.

    该值默认为false, 即不允许一个application同时存在一个以上的avtive 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实例的步骤如下:

    1. 通过SparkContext伴生对象object SparkContext中维护了一个对象 SPARK_CONTEXT_CONSTRUCTOR_LOCK, 单例SparkContext在一个进程中是唯一的, 所以SPARK_CONTEXT_CONSTRUCTOR_LOCK在一个进程中也是唯一的

    2. 函数markPartiallyConstructed中通过synchronized方法保证同一时间只有一个线程能处理

        assertNoOtherContextIsRunning(sc, allowMultipleContexts)
        contextBeingConstructed = Some(sc)
      

    assertNoOtherContextIsRunning会检测是否有其他SparkContext对象正在被构造或已经构造完成, 若allowMultipleContexts为true且确有正在或者已经完成构造的SparkContext对象, 则抛出异常, 否则完成SparkContext对象构造

    看到这里, 有人可能会有疑问, 这虽然能保证在一个进程内只有唯一的SparkContext对象, 但Spark是分布式的, 是不是无法保证在在其他节点的进程内会构造SparkContext对象. 其实并不存在这样的问题, 因为SparkContext只会在Driver中得main函数中声明并初始化, 也就是说只会在Driver所在节点的一个进程内构造.


    欢迎关注我的微信公众号:FunnyBigData

    FunnyBigData

    相关文章

      网友评论

      • 一泓_秋水:官方文档里好像没找到这个配置项,也没有关于多个sparkcontext的说明,这个用起来会有什么问题吗
        牛肉圆粉不加葱:@一泓_秋水 这个我倒是没试过。对于这种情况,我的建议还是分成两个 app(如果你的目的仅仅是两个 DStream 的 interval 不同的话),如果不是你可以继续描述~
        一泓_秋水:@牛肉圆粉不加葱 我现在有这样一种业务场景,想在一个spark streaming程序里实现两个不同interval的流,可以通过开启allowMultipleContexts这个选项,初始化两个不同的SparkContext,再在其上分别初始化两个不同的StreamingContext吗?我看stackoverflow上有人说不建议这么使用,想请教下博主是否可以这么用,会不会有坑
        牛肉圆粉不加葱:@一泓_秋水 默认就会保证的 你可以当做不知道 原来怎么用依旧怎么用
      • 牛肉圆粉不加葱:@七月这天 嗯 这篇文章说的就是这种情况
      • 309ff0e18470:@牛肉圆粉不加葱 恩 我说的当然不是一个application,而是多个application使用同一个spark集群。
      • 牛肉圆粉不加葱:@七月这天 一个application同一时刻不会有多个driver~
      • 309ff0e18470:如果有多个driver,同样会有多个sparkContext在不同jvm。

      本文标题:如何保证一个Spark Application只有一个Spark

      本文链接:https://www.haomeiwen.com/subject/ttfeqttx.html