Spark架构及运行机制(2) - Spark作业执行过程

Spark程序从提交到集群到执行的过程如下图:


(1)用户编写一个Spark程序(像之前编写的WordCount程序一样),在应用程序中包含一个用户自定义的主函数,在主函数内部实现RDD创建、RDD转换、RDD存储等操作。之后用户将完整的Spark程序提交到集群,申请Spark集群资源并执行该程序。集群收到用户提交的Spark程序后,对应的Driver进程将被启动,负责响应执行用户定义的主函数。Driver进程的启动有2种方式:
    1.Driver进程在客户端启动;
    2.Master节点指定一个Worker节点启动Driver进程,来充当Driver节点的角色;

(2)Driver进程响应执行用户定义的主函数后,会与Master节点通信,通过Master节点申请执行程序所需的资源;

(3)Spark集群中所有的Worker节点都会向Master节点注册,Master节点会通过心跳检查来检查已注册的Worker节点是否存活。在收到Driver进程的资源请求后,Master节点会命令已注册的Worker节点启动Executor进程;

(4)如果Worker节点是正常的,并且Worker节点上的Executor进程启动成功,Master节点就会将这些启动的资源通知Driver进程,使Driver进程使用集群中的那些资源来并行完成该Spark程序;

(5)Driver节点根据RDD在程序中的转换和执行情况对程序进行分割。将分割后的任务发送给已经申请的多个Executor资源,每个Executor进程负责独立完成分给它的那部分任务,并将执行的结果反馈给Driver;

(6)Worker节点上运行的Executor进程是作业的真正执行者,在每个Worker节点上可以启动多个Executor进程,每个Executor单独运行在一个JVM进程中,每个计划任务则运行在Executor中的一个线程。

(7)Driver通知Client应用程序执行完成;


在上面的过程中,最重要的是如下3个步骤:


(1)第一步:生成RDD
    Spark本身对RDD的操作模式是惰性计算。在惰性计算机制中,尽管每一次算子操作都会将一个RDD转换成一个新的RDD,并且逻辑上会顺序的执行这一系列计算,但是这些RDD的操作并不是立即执行的,而是会等到出现行动算子时才触发整个RDD操作序列,将之前的所有算子操作形成一个有向无环图(Directed Acyclic Graph,DAG),每个有向无环图再触发执行一个作业(Job)。例如,WordCount程序中,只有程序执行到saveAsTextFile时,Spark才对RDD进行真正的处理,将之前的flatMap、map、reduceByKey和saveAsTextFile这些算子连成一个有向无环图,并向Spark提交该作业。
    采用惰性计算的优势:
    1.相关的操作序列可以进行连续计算,不用为存储的中间结果离散的独立分配内存空间;
    2.节省存储空间,为之后对RDD变换操作的优惠提供了条件;

(2)第二步:生成Stage
    Driver节点中的DAGSchedule实例会对有向无环图中节点间的依赖关系进行遍历,将所有操作切分为多个调度阶段(Stage);

(3)第三步:生成Task
    每个Stage需要转换成任务在集群中的Worker节点上执行,因此,由Driver节点中的TaskSchedule实例将Stage转换为Task,并提交到Worker节点的Executor进程中执行;


猜你喜欢

转载自margaret0071.iteye.com/blog/2387073