Spark源码-branch-0.5 SparkContext与DAGScheduler

走读SparkContext初始化及DAGScheduler划分stage并提交任务代码,主要涉及在Driver进程中做的事。

SparkContext初始化

初始化环境,启动各组件:

  • SparkEnv在createFromSystemProperties方法中初始化其中的组件
    • cache: Cache,
    • serializer: Serializer,
    • closureSerializer: Serializer,
    • cacheTracker: CacheTracker,
    • mapOutputTracker: MapOutputTracker,
    • shuffleFetcher: ShuffleFetcher,
    • shuffleManager: ShuffleManager
  • Broadcast
  • Scheduler(DAGSchedular)
    此版本中Schedular只有LocalScheduler和MesosScheduler两种调度器

Scheduler初始化

private var scheduler: Scheduler = {
    // Regular expression used for local[N] master format
    val LOCAL_N_REGEX = """local\[([0-9]+)\]""".r
    // Regular expression for local[N, maxRetries], used in tests with failing tasks
    val LOCAL_N_FAILURES_REGEX = """local\[([0-9]+),([0-9]+)\]""".r
    master match {
      case "local" => 
        new LocalScheduler(1, 0)
      case LOCAL_N_REGEX(threads) => 
        new LocalScheduler(threads.toInt, 0)
      case LOCAL_N_FAILURES_REGEX(threads, maxFailures) =>
        new LocalScheduler(threads.toInt, maxFailures.toInt)
      case _ =>
        MesosNativeLibrary.load()
        new MesosScheduler(this, master, frameworkName)
    }
  }
  scheduler.start()

LocalScheduler初始化

通过Executors.newFixedThreadPool生成一个线程池,start方法为空

MesosScheduler初始化

todo

创建rdd及任务提交

创建rdd

最底层创建rdd的方法:

  • parallelize => ParallelCollection
  • hadoopRDD => HadoopRDD
  • hadoopFile => HadoopRDD
  • newAPIHadoopFile => NewHadoopRDD

所有rdd继承抽象类RDD,其构造函数如下:

abstract class RDD[T: ClassManifest](@transient sc: SparkContext)

可以看到,每个rdd都依赖SparkContext(sc),而以上创建rdd的方法在初始化rdd时会将当前sc注入rdd;rdd通过transform算子互相依赖,这个sc可以被rdd形成dag的最后一个rdd引用到,在action算子中调用sc的SparkContext.runJob方法进行任务触发。

SparkContext.runJob方法调用Scheduler的Scheduler.runJob方法进行stage划分及任务提交。

stage提交

DAGScheduler.runJob方法中执行stage划分、任务提交、任务调度

stage划分

主要涉及的方法

  • newStage
  • getParentStages
  • getShuffleMapStage

newStage方法作为stage划分入口,初始时DAGScheduler调用该方法生成最后一个stage(从后向前逆向遍历rdd依赖形成的dag)。

实际遍历dag是由getParentStages进行的,遍历方式为递归实现的dfs,每访问一个rdd,其依赖类型为ShuffleDependency,会触发stage划分。

stage划分由getShuffleMapStage执行,在stage划分阶段,该方法内部调用newStage生成新stage返回给getParentStages,再返回给上一层newStage方法,作为依赖注入上一层newStage方法实例化的Stage对象,从而构建Stage依赖链,完成stage划分。其创建的stage会被存入DAGScheduler的shuffleToMapStage,一个HashMap

由于stage是在ShuffleDependency处划分,除了最后一个stage外,newStage方法中都会将shuffle注册到MapOutputTracker;另外rdd也在newStage方法中注册到CacheTracker。

Stage对象中保存的信息:

class Stage(
    val id: Int,                                      // stage id
    val rdd: RDD[_],                                  // 当前stage最后一个rdd
    val shuffleDep: Option[ShuffleDependency[_,_,_]], // 当前stage最后一个rdd下游rdd的shuffle依赖
    val parents: List[Stage]                          // 当前stage的父stage
    ) {}

stage提交

主要涉及的方法

  • submitStage
  • getMissingParentStages:dfs遍历rdd的方式找到当前stage未完成的父stage
  • submitMissingTasks

submitStage中调用getMissingParentStages获取当前stage未完成的父stage。若其父stage都已完成,则调用submitMissingTasks提交当前stage;否则对所有未完成的父stage递归调用submitStage。递归的方式从最初stage开始提交。

submitMissingTasks实际执行stage的提交,若当前stage为整个dag最后一个stage,则提交ResultTask类型任务;否则提交ShuffleMapTask类型任务。任务提交调用submitTasks方法(由具体DAGScheduler实现重写)。

结束

任务提交之后,driver在循环中监听事件,对任务执行状况进行调度、监控。具体细节待研究。当接收到成功事件时,若成功的为ResultTask,则job执行完毕;当成功的为ShuffleMapTask,会将成功的stage的输出通过registerMapOutputs方法注册到MapOutputTracker。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值