大数据批式计算引擎Spark---SparkCore | 青训营笔记

153 阅读3分钟

这是我参与「第四届青训营 」笔记创作活动的第 9 天

  之前我们简单介绍了Spark框架,由此我们知道Spark的生态组件主要有以下几种:Spark Core、 Spark SQL、 Spark Structured Streaming、在各种Cluster Manager运行(独立调度器、Yarn、Mesos、Kubernetes)、 MLlib、 GraphX。

  本篇笔记我们主要讲解下Spark Core,我们需要认识spark的核心概念RDD,RDD两种算子处理过程,理解RDD依赖,学习RDD在Spark中的执行流程。

1. RDD概述

1.1 什么是RDD

RDD(Resilient Distributed Dataset) 叫做弹性分布式数据集,是Spark中最基本的数据抽象,是一个容错的、并行的数据结构。

在代码中是一个抽象类,它代表一个弹性的、不可变的、可分区且里面的元素可并行计算的集合。

1.2 RDD特性

* Internally, each RDD is characterized by five main properties:
*
* - A list of partitions
* - A function for computing each split
* - A list of dependencies on other RDDs
* - Optionally,a Partitioner for key-value RDDs (e.g. to say that the RDD is hash-partitioned
* - 0ptionally, a list of preferred locations to compute each split on (e.g. block locations for an HDFS file)

(1)一组分区(Partition),即是数据集的基本组成单位,标记数据是哪个分区的;
    protected def getPartitions:Array[Partition]

(2)一个计算每个分区的函数;
    def compute(split: Partition, context: TaskContext): Interator[T]

(3)RDD之间的依赖关系;
    protected def getDependencies: Seq[Dependency[ ]]=deps

(4)一个Partitioner,即RDD的分片函数;控制分区的数据流向(键值对)
    val partitioner : scala.Option[org.apache.spark.Partitioner]

(5)一个列表,存储存取每个Partition的优先位置( preferred location) 。 移动数据不如移动计算,除非资源不够。
    protected def getPreferredLocations(split : Partition ) : scala.Seq[String]

2. RDD的两种算子

RDD算子:对任何函数进行某一项操作都可以认为是一个算子,RDD算子是RDD的成员函数

2.1 Transform(转换)算子

根据已有RDD创建新的RDD

2.2 Action(动作)算子

将在数据集上运行计算后的数值返回到驱动程序,从而触发真正的计算。因为转换算子都是懒加载,并不会立即执行。

3. RDD依赖

3.1 窄依赖

窄依赖表示每一个父RDD的Partition最多被子RDD的一个Partition使用(一对一 or 多对一)。 窄依赖可以被比喻为独生子女。

image.png

3.2 宽依赖

宽依赖表示同一个父RDD的Partition被多个子RDD的Partition依赖(只能是一对多),会引起Shuffle。 宽依赖可以被比喻为超生。

image.png

4. RDD执行过程

image.png 划分Stage的整体思路:从后往前推,遇到宽依赖就断开,划分为一个Stage。遇到窄依赖,就将这个RDD加入该Stage中,DAG最后一个阶段会为每个结果的Partition生成一个ResultTask。每个Stage里面的Task数量由最后一个RDD的Partition数量决定,其余的阶段会生成ShuffleMapTask。

  1. 当RDD对象创建后,SparkContext会根据RDD对象构建DAG有向无环图,然后将Task提交给DAGScheduler。
  2. DAGScheduler根据ShuffleDependency将DAG划分为不同的Stage,为每个Stage生成TaskSet任务集合,并以TaskSet为单位提交给TaskScheduler。
  3. TaskScheduler根据调度算法(FIFO/FAIR)对多个TaskSet进行调度,并通过集群中的资源管理器(Standalone模式下是Master,Yarn模式下是ResourceManager)把Task调度(locality)到集群中Worker的Executor,Executor由SchedulerBackend提供。