• Spark DAG及内存迭代计算


    DAG

    • Spark的核心是根据RDD来实现的,Spark Scheduler则为Spark核心实现的重要一环,其作用就是任务调度。Spark的任务调度就是如何组织任务去处理RDD中每个分区的数据,根据RDD的依赖关系构建DAG,基于DAG划分Stage,将每个Stage中的任务发到指定节点运行。基于Spark的任务调度原理,可以合理规划资源利用,做到尽可能用最少的资源高效地完成任务计算。
    • DAG也叫有向无环图,即有方向,没有闭环的图,如下WordCount DAG图所示:
      在这里插入图片描述
    • DAG作用就是表示代码的逻辑执行流程。

    Job与Action之间的关系

    • 通常一个Action会产生一个DAG,会在程序中产生一个Job,所以一个Action = 一个DAG = 1个Job。之间的层级关系:1个application中可以包含多个job,每个Job中有一个DAG,每个Job是由一个Action产生的。

    DAG和分区

    • DAG是Spark代码的逻辑执行图,这个DAG的最终作用就是为了构建物理上的Spark详细执行计划,所以由于Spark是分布式多分区的,DAG与分区之间还是有关联的。还是以上图WordCount DAG图为例,该图在textFile步骤上就执行3分区,全部的RDD就在3个分区上执行。

    DAG宽窄依赖

    • 窄依赖:父RDD的一个分区,全部将数据发给子RDD一个分区。
    • 宽依赖(shuffle):父RDD的一个分区,将数据发给子RDD多个分区。
    • 我们可以看下图来真正地去理解宽窄依赖。
      在这里插入图片描述
      在这里插入图片描述

    DAG宽窄依赖的划分

    • Spark根据DAG的宽窄依赖划分为不同的DAG阶段,划分依据是从后往前,遇到宽依赖就会划分出一个阶段,这个阶段也称为stage。如下图所示:
      在这里插入图片描述
    • 该图在DAG中,基于宽依赖,将DAG划分成了2个stage,后面的为stage0,前面的为stage1,在stage内部一定都是窄依赖。

    Spark内存迭代计算

    • 根据上图的描述,基于带有分区的DAG以及阶段划分,可以从图中得到逻辑上最优的task分配,一个task是由一个线程来具体执行的,task对于rdd这一条执行的计算过程的直线(纯内存计算)也叫内存计算管道。
    • Spark默认收到了全局并行度的限制,除了个别算子由特殊分区的情况,大部分算子都会遵循全局并行度要求,来规划自己的分区数。Spark一般推荐只设置全局的并行度,不要再算子上再加上并行度(除了一些排序算子外)。

    总结

    Spark是怎么做内存计算的?DAG的作用?Stage阶段划分作用?

    • Spark会产生DAG图。
    • DAG图会基于分区和宽窄依赖关系划分阶段。
    • 一个阶段内部都是窄依赖,窄依赖内,如果形成前后的1:1的分区对应关系,就可以产生许多内存迭代计算管道。
    • 这些内存迭代计算的管道,就是一个个具体执行的Task。
    • 一个Task就是一个具体的线程,任务跑在一个线程内,就是走内存计算了。

    Spark为什么比MapReduce快?

    • 从编程模型上来看,Spark算子多,处理速度快。MR编程模型很难在一套MR中处理复杂任务,需要些多套MR进行串联,多个MR串联通过磁盘交互数据,就很慢。Spark可以执行内存迭代,算子间形成DAG基于依赖划分阶段后,在阶段内形成内存迭代管道,但是MR的交互还是通过磁盘来实现。所以速度就很慢。
  • 相关阅读:
    kafka消费者理解
    8086汇编段地址和偏移地址分配原则,深入理解.
    [100天算法】-实现 Trie(day 41)
    Gradle系列【5】任务Task
    C# 显示OpenCV的mat对象图像
    【大数据】Neo4j 图数据库使用详解
    Secure Boot(安全启动)
    Latex——换行换段
    mysql数据库备份与回滚
    改进教学的优化算法(Matlab代码实现)
  • 原文地址:https://blog.csdn.net/sinat_31854967/article/details/128002554