Spark 介绍

    技术2022-07-11  79

    1. spark RDD介绍

    RDD:弹性分布式数据集(Resilient Distributed Dataset)。RDD是Spark的最基本抽象,是对分布式内存的抽象使用,实现了以操作本地集合的方式来操作分布式数据集的抽象实现。RDD是Spark最核心的东西,它表示已被分区,不可变的并能够被并行操作的数据集合,不同的数据集格式对应不同的RDD实现。RDD必须是可序列化的。RDD可以cache到内存中,每次对RDD数据集的操作之后的结果,都可以存放到内存中,下一个操作可以直接从内存中输入,省去了MapReduce大量的磁盘IO操作。这对于迭代运算比较常见的机器学习算法, 交互式数据挖掘来说,效率提升比较大。

    弹性:指的是容错的能力,引擎会根据rdd之间的上下游关系、以及不同分片的数据来源,如果一部分分片或者rdd失败了,会根据血缘关系来重算。

    分布式:一个rdd是有多个partition的,是为了进行分布式的并行计算。

    在 Spark 中,对数据的所有操作不外乎创建 RDD、转化已有 RDD 以及调用 RDD 操作进行求值。而在这一切背后,Spark 会自动将RDD 中的数据分发到集群上,并将操作并行化执行。Spark 中的 RDD 就是一个不可变的分布式对象集合。每个 RDD 都被分为多个分区,这些分区运行在集群中的不同节点上。RDD 可以包含 Python、Java、Scala 中任意类型的对象,甚至可以包含用户自定义的对象。

    RDD 支持两种操作:转化操作 Transformation 和行动操作 Action 。RDD 的转化操作是返回一个新的 RDD 的操作,比如 map() 和 filter(),比如常见map、flatmap、union、filter,另外通过key进行操作,reduceBykey、groupByKey、distinct、join,而行动操作则是向驱动器程序返回结果或把结果写入外部系统的操作,会触发实际的计算,比如 count() 和 first()、collect、take、foreach。Spark 对待转化操作和行动操作的方式很不一样,因此理解你正在进行的操作的类型是很重要的。如果对于一个特定的函数是属于转化操作还是行动操作感到困惑,你可以看看它的返回值类型:转化操作返回的是 RDD,而行动操作返回的是其他的数据类型。

    RDD 的转化操作是返回新 RDD 的操作。转化出来的 RDD 是惰性求值的,只有在行动操作中用到这些 RDD 时才会被计算。许多转化操作都是针对各个元素的,也就是说,这些转化操作每次只会操作 RDD 中的一个元素。不过并不是所有的转化操作都是这样的。Spark 会在内部记录下所要求执行的操作的相关信息。我们不应该把 RDD 看作存放着特定数据的数据集,而最好把每个 RDD 当作我们通过转化操作构建出来的、记录如何计算数据的指令列表。把数据读取到 RDD 的操作也同样是惰性的。因此,当我们调用sc.textFile() 时,数据并没有读取进来,而是在必要时才会读取。和转化操作一样的是,读取数据的操作也有可能会多次执行。

    2.Spark--DAG划分

    DAG:有向无环图,分为三个层次,Job、stage、Task

    Job :遇到RDD的action操作,比如count(),就会从RDD的最后往前回溯,生成一个有向无环图。实际上是RDD的生产->转换->返回结果的过程。job里面分为StageStage:根据Shuffle来划分,确定是否在一个节点传数据。遇到shuffle,则将shuffle之前的窄依赖归来一个stage; 宽依赖(有shuffle):groupByKey、join等 (有在不同物理节点之间chua)窄依赖(无shuffle):map、filtertask:一个Stage里计算RDD一个partition的数据

    1.先由sparkcontext初始化,创建一个DAGshcheduler,启动一个监听器,监听spark任务,spark拆分的所有任务都会发给这个监听器;

     2.客户端这边,当我们调用action时,则action会向sparkcontext启动一个runjob,即是将action任务(一个job)提交给DAGshcheduler的监听器;

    3.接到job的DAGscheduler 会将任务交给handleJobSubmitted 来处理;

    4. 每个job会生成一个resultstage,其余的都是shufflestage,shufflestage是根据rdd的宽依赖来生成的,根据广度优先遍历rdd,遇到shufflestage就创建一个新的stage;

    5.形成DAG图之后,遍历执行stage列表,根据父子stage顺序执行,如果上层未执行完,下层会一直等待;

    6.每个stage会拆分成多个task,交由taskshcheduler来分配,等待executor来执行完一个task后交给下一个task;

    DAG源码解析:

    https://www.cnblogs.com/yankang/p/9769720.html

    https://www.cnblogs.com/yankang/p/9771778.html

    Processed: 0.008, SQL: 9