概念
Job
当在RDD上执行Action操作时就会提交一个Job。这个Job会将RDD分为多分,并将每份RDD提交到集群执行。
Stage
当一个Job提交后将分解为多个Stage。
Task
一个Stage可分解为多个Task。Task分为Shuffle map Task和Result Task。其中Shuffle map Task任务是将一个现有的RDD转化为一个新的RDD。Result Task在RDD上执行action操作,计算RDD结果并将结果返回驱动器。
scheduler
调度器分为两部分:
- DAG调度器:将一个作业分解一个包含多个阶段的DAG。
- 任务调度器:负责将每阶段的任务提交到集群
Spark执行流程
当提交一个作业后,Spark需要驱动器和执行器分别执行一些流程,驱动器执行流程:
执行器流程:
此流程为类级别流程,在Spark源码中均可以找到对应的类。
1. Run Job
当在RDD上执行action操作时,会触发SparkContext调用DAGScheduler方法runJob提交一个作业。输入参数包括:
- rdd,目标rdd
- func,需要在RDD上执行的函数
- partitions,需要在RDD上执行函数的部分。
- resultHandler,需要在每个结果上执行的回调函数。
2. Submit Tasks
sparkContext提交的job不能直接直接转化为Task,需要先转化为Stage然后转化为Task集合,提交给TaskScheduler。
3. Assign Task
执行任务涉及需要在哪里执行。TaskScheduler任务分配策略是依据传输远近按照以下顺序执行,同处理器,同节点,同机架。
4. Send task
SchedulerBackend将task消息发送到集群的Executor节点。
5. Launch task
executor执行task任务。executor执行Task任务分为三个步骤:
- 检查任务执行需要的资源是否是最新的,包括Jar包或者文件依赖。executor会在本地缓存上一个任务的依赖,基于此缓存机制,executor仅需下载有改动资源。
- 从任务消息中反序列化任务代码,代码以二进制方式传输。
- 执行任务代码,由于和executor使用同一个JVM,执行任务时没有额外的进程开销。
6. Run Task
Task可以将结果返回给Driver。Task首先将结果序列化并返回给executor的backend,然后作为状态更新消息返回给driver。shuffle map任务结果允许下一阶段获取当前阶段输出,result任务直接返回该片区的结果,驱动器将各个片区结果组装返回给用户程序。
问题
提交给executor的RDD是如何分片的?
Job执行过程中是不会重新对RDD进行分片的。RDD分片工作是在生成RDD,提交Job前执行的。RDD分片方法是当Spark从HDFS读取一个文件,它将为每个输入切分创建一个分片。输入切分是由Hadoop InputFormat使用的。例如如果你使用textFile方法,那么它的格式是TextInputFormat,对于未压缩的文件每个HDFS的块都将创建一个分片。由于压缩文件是不可切分的,对于压缩文件每个文件仅创建一个分片,不管文件由多大。例如如果你有一个30G未压缩的HDFS文件,默认每个HDFS块大小未128MB,那么你将拥有235个分片。
除了默认分片方法外,Spark支持手动调整分片数量,通过调用RDD的repartition(num)方法,可以重新将RDD调整为num个分片。该方法时惰性执行的,只有执行action操作才会执行重新分片。