《循序渐进学Spark》一第3章-阿里云开发者社区

开发者社区> 华章出版社> 正文

《循序渐进学Spark》一第3章

简介:

本节书摘来自华章出版社《循序渐进学Spark》一书中的第3章,第3.1节,作者 小象学院 杨 磊,更多章节内容可以访问云栖社区“华章计算机”公众号查看。



第3章

Spark机制原理

本书前面几章分别介绍了Spark的生态系统、Spark运行模式及Spark的核心概念RDD和基本算子操作等重要基础知识。本章重点讲解Spark的主要机制原理,因为这是Spark程序得以高效执行的核心。本章先从Application、job、stage和task等层次阐述Spark的调度逻辑,并且介绍FIFO、FAIR等经典算法,然后对Spark的重要组成模块:I/O与通信控制模块、容错模块及Shuffle模块做了深入的阐述。其中,在Spark I/O模块中,数据以数据块的形式管理,存储在内存、磁盘或者Spark集群中的其他机器上。Spark集群通信机制采用了AKKA通信框架,在集群机器中传递命令和状态信息。另外,容错是分布式系统的一个重要特性,Spark采用了lineage与checkpoint机制来保证容错性。Spark Shuffle模块借鉴了MapReduce的Shuffle机制,但在其基础上进行了改进与创新。

3.1 Spark应用执行机制分析

下面对Spark Application的基本概念和执行机制进行深入介绍。

3.1.1 Spark应用的基本概念

Spark应用(Application)是用户提交的应用程序。Spark运行模式分为:Local、Standalone、YARN、Mesos等。根据Spark Application的Driver Program是否在集群中运行,Spark应用的运行方式又可以分为Cluster模式和Client模式。

下面介绍Spark应用涉及的一些基本概念:

1) SparkContext:Spark 应用程序的入口,负责调度各个运算资源,协调各个Worker Node 上的Executor。

2) Driver Program:运行Application的main()函数并创建SparkContext。

3) RDD:前面已经讲过,RDD是Spark的核心数据结构,可以通过一系列算子进行操作。当RDD遇到Action算子时,将之前的所有算子形成一个有向无环图(DAG)。再在Spark中转化为Job(Job的概念在后面讲述),提交到集群执行。一个App中可以包含多个Job。

4) Worker Node:集群中任何可以运行Application代码的节点,运行一个或多个Executor进程。

5) Executor:为Application运行在Worker Node上的一个进程,该进程负责运行Task,并且负责将数据存在内存或者磁盘上。每个Application都会申请各自的Executor来处理任务。

下面介绍Spark 应用(Application)执行过程中各个组件的概念:

1) Task(任务):RDD中的一个分区对应一个Task,Task是单个分区上最小的处理流程单元。

2) TaskSet(任务集): 一组关联的,但相互之间没有Shuffle依赖关系的Task集合。

3) Stage(调度阶段):一个TaskSet对应的调度阶段。每个Job会根据RDD的宽依赖关系被切分很多Stage,每个Stage都包含一个TaskSet。

4) Job(作业): 由Action算子触发生成的由一个或多个Stage组成的计算作业。

5) Application:用户编写的Spark的应用程序,由一个或多个Job组成。提交到Spark之后,Spark为Application分配资源,将程序转换并执行。

6) DAGScheduler:根据Job构建基于Stage的DAG,并提交Stage给TaskScheduler。

7) TaskScheduler:将Taskset提交给Worker Node集群运行并返回结果。

以上基本概念之间的关系如图3-1所示。

3.1.2 Spark应用执行机制概要

Spark Application从提交后到在Worker Node执行,期间经历了一系列变换,具体过程如图3-2所示。

 

图3-1 Spark基本概念之间的关系

37967107371693127d4a761bf93f9e9bcb8bc8c1

 

图3-2 Spark 执行流程

53cfb227b2ae1bfae536e37a5ed3069878367630

如图3-2所示,前面讲过,当RDD遇见Action算子之后,触发Job提交。提交后的Job在Spark中形成了RDD DAG有向无环图(Directed Acyclic Graph)。RDD DAG经过DAG Scheduler调度之后,根据RDD依赖关系被切分为一系列的Stage。每个Stage包含一组task集合,再经过Task Scheduler之后,task被分配到Worker节点上的Executor线程池执行。如前文所述,RDD中的每一个逻辑分区对应一个物理的数据块,同时每个分区对应一个Task,因此Task也有自己对应的物理数据块,使用用户定义的函数来处理。Spark出于节约内存的考虑,采用了延迟执行的策略,如前文所述,只有Action算子才可以触发整个操作序列的执行。另外,Spark对于中间计算结果也不会重新分配内存,而是在同一个数据块上流水线操作。

Spark使用BlockManager管理数据块,在内存或者磁盘进行存储,如果数据不在本节点,则还可以通过远端节点复制到本机进行计算。在计算时,Spark会在具体执行计算的Worker节点的Executor中创建线程池,Executor将需要执行的任务通过线程池来并发执行。

3.1.3 应用提交与执行

Spark使用Driver进程负责应用的解析、切分Stage并调度Task到Executor执行,包含DAGScheduler等重要对象。Driver进程的运行地点有如下两种:

1) Driver进程运行在Client端,对应用进行管理监控。

2) Master节点指定某个Worker节点启动Driver进程,负责监控整个应用的执行。

针对这两种情况,应用提交及执行过程分别如下:

1. Driver运行在Client

用户启动Client端,在Client端启动Driver进程。在Driver中启动或实例化DAGS-

cheduler等组件。

1)Driver向Master注册。

2)Worker向Master注册,Master通过指令让Worker启动Executor。

3)Worker通过创建ExecutorRunner线程,进而ExecutorRunner线程启动Executor-Backend进程。

4)ExecutorBackend启动后,向Client端Driver进程内的SchedulerBackend注册,因此Driver进程就可以发现计算资源。

5)Driver的DAGScheduler解析应用中的RDD DAG并生成相应的Stage,每个Stage包含的TaskSet通过TaskScheduler分配给Executor。在Executor内部启动线程池并行化执行Task。

2. Driver运行在Worker节点

用户启动客户端,客户端提交应用程序给Master。

1)Master调度应用,指定一个Worker节点启动Driver,即Scheduler-Backend。

2)Worker接收到Master命令后创建DriverRunner线程,在DriverRunner线程内创建SchedulerBackend进程。Driver充当整个作业的主控进程。

3)Master指定其他Worker节点启动Exeuctor,此处流程和上面相似,Worker创建ExecutorRunner线程,启动ExecutorBackend进程。

4)ExecutorBackend启动后,向Driver的SchedulerBackend注册,这样Driver获取了计算资源就可以调度和将任务分发到计算节点执行。

SchedulerBackend进程中包含DAGScheduler,它会根据RDD的DAG切分Stage,生成TaskSet,并调度和分发Task到Executor。对于每个Stage的TaskSet,都会被存放到TaskScheduler中。TaskScheduler将任务分发到Executor,执行多线程并行任务。

图3-3为Spark应用的提交与执行示意图。

37e922c32ca6732f9cc72e50cf2638a00ee06a1a

图3-3 Spark应用的提交与执行

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

分享:

华章出版社

官方博客
官网链接