背景知识:Spark基本工作原理、RDD

lv0

一个典型的Job是由以下过程组成:从数据源(Data blocks)加载生成RDD(每个数据分片Partition一般是128M,最后一条记录横跨2个blocks),后将RDD经过一系列转换(包括基本类型转换和洗牌)最终得到计算结果(result),再将结果汇总到driver端。往往由Action触发,每个Action对应一个Job。(后接1-1)
每个Job由一个或多个Stage构成,Stage根据宽依赖进行划分。各Stage之间是有前后关系的,只有前面的Stage完成计算才会执行下一个Stage。
每个Stage是由一组或多组Task组成的,是并行计算的实体,在Executor中执行。Task分为两类,一类为shuffleMapTask作为中间过程,另一类为resultTask作为最后的Task。其生命周期如下:①Driver中的CoarseGrainedSchedulerBackend(粗粒度后端调度)(序列化任务大小限制为128M)给CoarseGrainedExecutorBackend(粗粒度后端执行)发送的LaunchTask(Task启动指令)后,反序列化TaskDescription(Task任务描述)(第一次反序列化,共4次)。②Executor通过LaunchTask执行Task,通过new()函数创建TaskRunner。③TaskRunner通过ThreadPool运行具体的Task,通过run方法调用statusUpdate向Driver汇报状态为Running。④TaskRunner内部反序列化Task相关依赖(第二次反序列化,共4次),获取所需要的文件和jar。⑤反序列化Task本身(第三次反序列化,共4次)。⑥执行任务,Task通过runTask方法调用RDD的iteratior方法对Partition进行计算,其中对ShuffleMapTask中的元素先对RDD及其依赖关系进行反序列化(第四次反序列化,共4次),最终调用RDD的compute方法进行计算;而对ResultTask则根据rdd.iteratior最终调用compute执行。⑦执行结果序列化传给Driver。⑧CoarseGrainedExecutorBackend向DriverEndpoint发送StatusUpdate传输执行结果(该结果最大为1GB),DriverEndpoint会将结果传输给TaskSchedulerImpl处理,最终交给TaskResultGetter通过线程分别处理成功与失败两种情况,最终告诉DAGScheduler任务处理结束情况。

lv1-1

每个Action算子本质上是执行了sc的runJob方法,这是一个重载方法。核心是交给DAGScheduler中的submitJob执行,通过JobSubmitted对象给eventProcessLoop。eventProcessLoop实现了EventLoop中的onReceive方法,该方法回调doOnReceive经过模式匹配方式执行到JobSubmitted,在handleJobSubmitted中创建finalStage,建立与父Stage的依赖链条。