注意:此文的stage划分有错,stage的划分是以shuffle操作作为边界的,可以参考《spark大数据处理技术》第四章page rank例子!

参考:http://litaotao.github.io/deep-into-spark-exection-model

我们用一个例子来说明,结合例子和运行截图来理解。

1.1 例子,美国 1880 - 2014 年新生婴儿数据统计

  • 目标:用美国 1880 - 2014 年新生婴儿的数据来做做简单的统计
  • 数据源https://catalog.data.gov
  • 数据格式
    • 每年的新生婴儿数据在一个文件里面
    • 每个文件的每一条数据格式:姓名,性别,新生人数

  • 代码和结果展示
### packages
import pandas as pd
### spark UDF (User Defined Functions)
def map_extract(element):
file_path, content = element
year = file_path[-8:-4]
return [(year, i) for i in content.split("\r\n") if i]
### spark logic
res = sc.wholeTextFiles('hdfs://10.21.208.21:8020/user/mercury/names',
minPartitions=40) \
.map(map_extract) \
.flatMap(lambda x: x) \
.map(lambda x: (x[0], int(x[1].split(',')[2]))) \
.reduceByKey(operator.add) \
.collect()
### result displaying
data = pd.DataFrame.from_records(res, columns=['year', 'birth'])\
.sort(columns=['year'], ascending=True)
ax = data.plot(x=['year'], y=['birth'],
figsize=(20, 6),
title='US Baby Birth Data from 1897 to 2014',
linewidth=3)
ax.set_axis_bgcolor('white')
ax.grid(color='gray', alpha=0.2, axis='y')

1.2 运行流程概览

上面的 22 行代码,就已经把构建一个 spark app 的三大步骤完成了,amazing, right? 今天我们主要讲 spark 的运行逻辑,所以我们就以核心的 11 - 16 ,这六行代码来作为今天的主线,了解了解 spark 的原理。

可以看到,整个逻辑实际上就用了 sparkContext 的一个函数,rdd 的 3 个 transformation 和 1 个 action。

现在让我们从 WEB UI 上来看看,当我们运行这段代码的时候,后台都发生了什么。 可以看到,执行这段代码的时候,spark 通过分析,优化代码,知道这段代码需要一个 job 来完成,所以 web ui 上只有一个 job。值得深究的是,这个 job 由两个 stage 完成,这两个 state 一共有 66 个 task。

所以,这里我们就再次理解下 spark 里,job,stage,task 的概念:

  • 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 会按照执行顺序依次执行。
  • 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 类似的操作了。]

1.3 运行流程之 : job

根据上面的截图和再次重温,我们知道这个 spark 应用里只有一个 job,那就是因为我们执行了一个 collect 操作,即把处理后的数据全部返回到我们的 driver 上,进行后续的画图,返回的数据如下图:

1.4 运行流程之 : 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 操作时 : 在我们的应用中就是 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 写下的数据。

用实例说明Spark stage划分原理的更多相关文章

  1. Spark源码剖析(八):stage划分原理与源码剖析

    引言 对于Spark开发人员来说,了解stage的划分算法可以让你知道自己编写的spark application被划分为几个job,每个job被划分为几个stage,每个stage包括了你的哪些代码 ...

  2. 【Spark工作原理】stage划分原理理解

    Job->Stage->Task开发完一个应用以后,把这个应用提交到Spark集群,这个应用叫Application.这个应用里面开发了很多代码,这些代码里面凡是遇到一个action操作, ...

  3. 17、stage划分算法原理及DAGScheduler源码分析

    一.stage划分算法原理 1.图解 二.DAGScheduler源码分析 1. ###org.apache.spark/SparkContext.scala // 调用SparkContext,之前 ...

  4. [Spark内核] 第34课:Stage划分和Task最佳位置算法源码彻底解密

    本課主題 Job Stage 划分算法解密 Task 最佳位置算法實現解密 引言 作业调度的划分算法以及 Task 的最佳位置的算法,因为 Stage 的划分是DAGScheduler 工作的核心,这 ...

  5. Spark源码分析之三:Stage划分

    继上篇<Spark源码分析之Job的调度模型与运行反馈>之后,我们继续来看第二阶段--Stage划分. Stage划分的大体流程如下图所示: 前面提到,对于JobSubmitted事件,我 ...

  6. Spark技术内幕:Stage划分及提交源码分析

    http://blog.csdn.net/anzhsoft/article/details/39859463 当触发一个RDD的action后,以count为例,调用关系如下: org.apache. ...

  7. Spark技术内幕:Stage划分及提交源代码分析

    当触发一个RDD的action后.以count为例,调用关系例如以下: org.apache.spark.rdd.RDD#count org.apache.spark.SparkContext#run ...

  8. spark 中划分stage的思路

    窄依赖指父RDD的每一个分区最多被一个子RDD的分区所用,表现为 一个父RDD的分区对应于一个子RDD的分区 两个父RDD的分区对应于一个子RDD 的分区. 宽依赖指子RDD的每个分区都要依赖于父RD ...

  9. Spark生态以及原理

    spark 生态及运行原理 Spark 特点 运行速度快 => Spark拥有DAG执行引擎,支持在内存中对数据进行迭代计算.官方提供的数据表明,如果数据由磁盘读取,速度是Hadoop MapR ...

随机推荐

  1. 解决Vue循环中子组件不实时更新的问题

    问题描述 使用Element-UI中的table组件时会遇到一个常见的问题.当在el-table中调用子组件的时候会出现数据更新后,子组件没有重新渲染的问题. eg:资源列表中的健康度组件. 代码如下 ...

  2. git如何获取用户名和邮箱

    答: git config user.name  (获取用户名)   git config user.email (获取邮箱)

  3. vim的几个插件mark.vim ctrlp.vim等

    开发过程中, 保证语义的前提下, 尽量使用 短的 变量名: 如: 用 $map来代替 $condition, 因为在书写长的变量名的时候, 容易写错, 而排查错误, 还不容易找出来. vim在浏览和排 ...

  4. luogu P2073 送花 线段树

    思路&心路 一眼认定沙比提 写的比较慢,写了1小时吧 开心的交上去 卧槽,只有20? 不服不服,拿着题解的代码去对拍 Emma,<100没问题 100000数据错了,还只是错了一个数据 ...

  5. hdu 6444 Neko's loop 单调队列优化DP

    Neko's loop Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total ...

  6. AtCoder 杂题训练

    前言: 因为要普及了,今年没一等就可以退役去学文化课了,所以暑假把历年noip普及组都刷了一遍,离noip还有50+天,想弄点强化训练什么的. 想了想,就这些天学文化课之余有空就把AtCoder之前那 ...

  7. Unity3D学习笔记(十六):Animator新动画

    新动画系统: 给模型选择动画类型 普通动画:Generic 人形动画:Humanoid 建立动画控制器 - 在Project右击 - 选择Create-AnimatorContorller 将对应动画 ...

  8. NRF24L01 射频收发 使用方法

    在干啥 这两天在调nrf24l01,最终还是参考正点原子的例程才调通,看芯片手册太难了 还要说啥废话 废话说到这,接下来上代码 SPI协议 spi.c #include "spi.h&quo ...

  9. hdu 2586 How far away ? 带权lca

    How far away ? Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) P ...

  10. jekins,报错 stderr: Could not create directory '/usr/share/tomcat7/.ssh'. Failed to add the host to the list of

    public key是在~/.ssh/id_rsa.pub,而private key是~/.ssh/id_rsa 设置的时候,Jenkins需要的是private key