http://litaotao.github.io/deep-into-spark-exection-model
1.what这个技术是什么
官方文档定义
spark 里,job,stage,task 的概念:
- application(应用):其实就是用spark-submit提交的程序
- job : A job is triggered by an action, like count() or saveAsTextFile(). Click on a job to see information about the stages of tasks inside it. 理解了吗,所谓一个 job,就是由一个 rdd 的 action 触发的动作,可以简单的理解为,当你需要执行一个 rdd 的 action 的时候,会生成一个 job。
- stage : stage 是一个 job 的组成单位,就是说,一个 job 会被切分成 1 个或 1 个以上的 stage,然后各个 stage 会按照执行顺序依次执行。至于 job 根据什么标准来切分 stage,可以回顾第二篇博文:『 Spark 』2. spark 基本概念解析
- task : A unit of work within a stage, corresponding to one RDD partition。即 stage 下的一个任务执行单元,一般来说,一个 rdd 有多少个 partition,就会有多少个 task,因为每一个 task 只是处理一个 partition 上的数据。从 web ui 截图上我们可以看到,这个 job 一共有 2 个 stage,66 个 task,平均下来每个 stage 有 33 个 task,相当于每个 stage 的数据都有 33 个 partition [注意:这里是平均下来的哦,并不都是每个 stage 有 33 个 task,有时候也会有一个 stage 多,另外一个 stage 少的情况,就看你有没有在不同的 stage 进行 repartition 类似的操作了。]
2.why为什么有这个技术
此技术解决什么问题
- 提交application,构建Spark Application的运行环境,启动SparkContext
- SparkContext向资源管理器(可以是Standalone,Mesos,Yarn)申请运行Executor资源,并启动StandaloneExecutorbackend,
- Executor向SparkContext申请Task
- SparkContext将应用程序分发给Executor
- SparkContext构建成DAG图,将DAG图分解成Stage、将Taskset发送给Task Scheduler,最后由Task Scheduler将Task发送给Executor运行
- Task在Executor上运行,运行完释放所有资源
3.how怎么学这个技术
运行流程之 : job
根据上面的截图和再次重温,我们知道这个 spark 应用里只有一个 job,那就是因为我们执行了一个 collect
操作,即把处理后的数据全部返回到我们的 driver 上,进行后续的画图,返回的数据如下图:
job数不等于stage数例子(每个action操作是一个job。而每一个宽依赖将会产生一个stage):http://blog.sina.com.cn/s/blog_6dd718930102xgm3.html
运行流程之 : stage
我们这个 spark 应用,生成了一个 job,这个 job 由 2 个 stage 组成,并且每个 stage 都有 33 个task,说明每个 stage 的数据都在 33 个 partition 上,这下我们就来看看,这两个 stage 的情况。
首先,我们先看看为什么这里会有两个 stage,根据 『 Spark 』2. spark 基本概念解析 中对 stage 的描述,目前有两个划分 stage 的标准:
- 当触发 rdd 的 action 时 : 在我们的应用中就是最后的
collect
操作,关于这个操作的说明,可以看官方文档: rdd.collect - 当触发 rdd 的 shuffle 操作时 (宽依赖往往对应着shuffle操作,需要在运行过程中将同一个父RDD的分区传入到不同的子RDD分区中): 在我们的应用中就是
reduceByKey
这个操作,官方文档: rdd.reduceByKey
再次回顾上面那张图:
这下应该就明了了,关于两个 stage 的情况:
-
第一个 stage,即截图中 stage id 为 0 的 stage,其执行了
sc.wholeTextFiles().map().flatMap().map().reduceByKey()
这几个步骤,因为这是一个Shuffle
操作,所以后面会有Shuffle Read
和Shuffle Write
。具体来说,就是在 stage 0 这个 stage 中,发生了一个 Shuffle 操作,这个操作读入 22.5 MB 的数据,生成 41.7 KB 的数据,并把生成的数据写在了硬盘上。 -
第二个 stage,即截图中 stage id 为 1 到 stage,其执行了
collect()
这个操作,因为这是一个action
操作,并且它上一步是一个 Shuffle 操作,且没有后续操作,所以这里collect()
这个操作被独立成一个 stage 了。这里它把上一个 Shuffle 写下的数据读取进来,然后一起返回到 driver 端,所以这里可以看到他的Shuffle Read
这里刚好读取了上一个 stage 写下的数据。
1.5 运行流程之 : task
其实到这里应该都理解得差不多了,至于为什么每个 stage 会有 33 个 task [即我们的数据文件存放到 33 个partition 上。