Spark之基本概念篇(RDD ,DAG,Task,TaskSet ,Stage,Shuffer,Job,dependency,Application,SparkContext)(3)

一  SparkContext

1  Spark程序的灵魂 ,用来创建最开始的RDD ;

2  在创建SparkContext 过程中 ,创建了 RpcEndPoint / DAGScheduler / TaskScheduler / ShuffleManager / BlockManager等 ,这些统称为 Driver ;

一个 SparkContext 就对应一个 Driver ;

一个 Application 中只能有一个SparkContext .

二  RDD

1  什么是RDD

RDD 的全称是 Resilient Distributed Dataset ,是一个弹性的 ,可复原(可容错)分布式数据集

是 Spark 中最基本的抽象数据集,是一个不可变的 / 有多个分区的 / 可以并行计算的集合 . RDD 中并不装真正要计算的数据 ,而装的是描述信息 ,描述以后从哪里读取数据 ,调用什么方法 ,传入什么函数 ,以及依赖关系等 .

可以认为是一个代理 ,你对RDD进行操作 ,相当于在Driver端先是记录下计算的描述信息 ,然后生成Task ,将Task 调度到 Executor端才执行真正的计算逻辑 .

2  RDD(有弹性/可复原/分布式的数据集)  的特点

1  有一些列连续的分区 : 分区编号从0开始,分区的数量决定了对应阶段Task的并行度

1) 如果是从 hdfs 中读取数据,分区的数量由hdfs中数据的输入切片数量决定

2) sc.textFile可以指定rdd的分区数量, 最小的分区数量为 2(如果不指定的话默认也是2)

3) 如果一个大文件,一个小文件, 大文件大小/(全部文件相加大小/最小分区数) > 1.1 倍 ,大文件会有指定的分区数输入切片

4) 当分区的数量大于切片的数量 ,多个Task可以读取一个输入切片;当分区的数量小于切片的数量,RDD分区的数量由切片数量决定

2  有一个函数作用在每个输入切片(分区)上 :每一个分区都会生成一个Task ,对该分区的数据进行计算 ,这个函数就是具体的计算逻辑

3  RDD 和 RDD 之间存在一些列依赖关系 : RDD 调用 Transformation 会生成一个新的 RDD ,子RDD 会记录父 RDD 的依赖关系,包括宽依赖(有 shuffle) 和窄依赖(没有 shuffle), 可以根据依赖关系恢复失败的任务和划分Stage

4  (可选的) K-V 的 RDD在 Shuffle 会有分区器 ,默认使用HashPartition ,分区器决定数据到下游哪个分区

5  (可选的) 如果从HDFS 中读取数据 ,会有一个最优位置,即将Executor中的Task调度到数据所在的节点上,要求Worker 和 DateNode部署在同一个节点或 Yarn 上 ,通过访问NameNode 获取数据块位置信息(spark 在调度任务之前会读取 NameNode的元数据信息 ,获取数据的位置 ,移动计算而不是移动数据 ,这样可以提高计算效率 ) .

3  RDD算子的分类

1) Transformation : 即转换算子 ,调用转换算子会生成一个新的RDD ,Transformation 是 Lazy 的,不会触发 job 执行 .

2) Action : 行动算子 ,调用行动算子会触发job执行 ,本质上是调用了 sc.runJob 方法 ,该方法从最后一个RDD,根据其依赖关系 ,从后往前 ,划分 Stage ,生成 TaskSet .

4  创建RDD的方法和查看RDD数量的方法

1  通过并行化方式 ,将Driver端的集合转为RDD (可以指定分区数量,默认是2个分区)
1.1 将Driver端的scala集合并行化成RDD,RDD中并没有真正要计算的数据,只是记录以后从集合中的哪些位置获取数据
val rdd1:RDD[Int] = sc.parallelize(Array(1,2,3,4,5,6))
val rdd1:RDD[Int] = sc.parallelize(Array(1,2,3,4,5,6) ,2)

2  从HDFS指定的目录创建RDD (可以指定分区数量)
2.1 指定以后从哪里读取创建RDD,可以是多种文件系统,需要指定文件系统的协议,如hdfs://,flile://,s3://等
val lines:RDD[String] = sc.textFile("hdfs://linux04:8020/wc")
val lines:RDD[String] = sc.textFile("hdfs://linux04:8020/wc" , 3)

3  查看RDD数量的方法
val rdd1:RDD[Int] = sc.parallelize(Array(1,2,3,4,5,6))
rdd1.partitions.length

5  RDD的数量分析

1)  读取 hdfs 中的目录有两个输入切片 ,最原始的 HadoopRDD的分区为2 ,以后没有改变RDD的分区数量的话 ,RDD的分区都是2 (Task 的数量取决于 Stage 中最后一个RDD分区的数量) .

2)  在调用 reduceByKey 方法时 ,有shuffle 产生, 要划分 Stage ,所以有两个 Stage ,Stage-0(ShuffleMapStage) 是前面的Stage ,在任务执行时先执行 ,Stage-1(ResultStage) 是后面的 ,等前面的任务执行完毕后才执行后面的 ;一个 Stage 对应一个 TaskSet ,一个TaskSet 中有一到多个Task ,但是 Task 的数量取决于 Stage 中最后一个RDD分区的数量 .

3)  第一个 Stage 的并行度为2 ,所以有 2 个Task ,并且为 ShuffleMapTask .第二个 Stage 的并行度也为 2 ,所以也有 2个 Task ,并且为 ResultTask ,所以一共有 4 个 Task .

总结 : 以上有两个输入切片 ,即有两个分区 (之后分区数一直没有改变),一个完整的 DAG ,一个 Job , 两个Stage(因为有一次shuffle产生) , 两个 TaskSet(一个stage对应一个taskset) , 四个Task (每个TaskSet 各有两个Task) , 两个输出文件 .

三  Application

1  使用 SparkSubmit 提交的一个计算应用  ;

2  一个Application 中可以触发多次 Action ,触发一次 Action 产生一个 Job ;

3  一个Application 中可以有一到多个 Job .

四  DAG

1  DAG 是指有向无环图(有方向 ,无闭环) ;

2  是对多个RDD转换过程和依赖关系的描述 ;

触发 Action 就会形成一个完整的 DAG ,一个DAG 对应一个 Job .

五  Job

Driver 端向 Executor 提交的作业 ,触发一次 Action 形成一个完整的 DAG ;

一个DAG 对应一个 Job ;

一个Job 中有一到多个Stage ,一个Stage 对应一个TaskSet ,一个TaskSet 中有一到多个 Task .

六  Stage

1  Stage 是指任务执行阶段 ;

2  Stage 执行是有先后顺序的 ,先执行前面的 ,再执行后面的 ;

一个Stage 对应一个TaskSet ,一个TaskSet 中的 Task 的数量取决于Stage 中最后一个RDD 分区的数量 .

七  TaskSet

1  是指保存同一种计算逻辑的多个Task 的集合 ;

2  一个TaskSet 中的Task 计算逻辑都一样 ,当时计算的数据不一样 (计算的数据来自不同的输入切片) .

八  Task

1  是Spark中任务最小的执行单位 ,Task 分类两种 ,即 ShuffleMapTask 和 ResultTask .

ShuffleMapTask : 

1) 可以读取各种数据源的数据

2) 也可以读取shuffle后的数据

3) 专门为shuffle做准备

ResultTask :

1) 可以读取各种数据源的数据

2) 也可以读取shuffle后的数据

3) 专门为了产生计算结果

Task 其实就是类的实例 ,有属性(从哪里读取数据/读取的是哪个切片的数据) ,有方法(如何计算 / 即数据的计算分析逻辑) ;

Task 的数量取决于Stage 中最后一个RDD分区的数量 ,Task 的数量决定并行度(分区数) ,同时也要考虑Spark 中可用的 cores .

九  Shuffer

需要通过网络将数据传输到多台机器 ,数据被打散 ,但是有网络传输 ,不一定就有shuffle ,shuffle也不一定走网络 ,只有调用Transformation算子 时才有 shuffle;

上游RDD的一个分区将数据给了下游RDD的多个分区 ,即是shuffle ,严格来说 ,shuffle 过程是下游的Task到上游的多个Task拉取数据 ,不是上游Task发送给下游的 ;

3  Shuffle 的功能是将具有一定规律的数据按照指定的分区器的分区规则 ,通过网络 ,传输到指定的一台机器的一个分区中即Task中 .

十  dependency

1  是指依赖关系 ,指的是父RDD和子RDD之间的依赖关系 ;

窄依赖没有shuffle产生 ,多个算子会被合并到一个Task 中 ,即在一个pipeline 中 ;

宽依赖有shuffle产生 ,是划分Stage的依据 .

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
1. RDD(Resilient Distributed Datasets):弹性分布式数据集,是Spark中最基本的数据抽象,是一个不可变的分布式对象集合,可以并行计算。RDD可以通过从Hadoop InputFormat中读取数据、在Spark中的其他RDD转换操作和从外部存储系统中获取数据创建。 2. DAG(Directed Acyclic Graph):有向无环图,它表示Spark任务执行的依赖关系。每个Spark应用程序都会生成一个DAG,用于描述任务之间的依赖关系。 3. Executor:执行器,是Spark中执行计算任务的工作进程。一个Spark应用程序可以由多个Executor组成,每个Executor都运行在独立的JVM进程中,负责运行Spark应用程序中的任务。 4. ApplicationSpark应用程序,是一个包含了用户编写的Spark任务代码和Spark集群上的资源配置信息的集合。在Spark中,应用程序通常以JAR包的形式提交到Spark集群中运行。 5. Task:任务,是Spark应用程序中最小的计算单元,是对RDD的一个分区进行操作的一段代码。每个Task都会被分配到一个Executor上运行。 6. Job:作业,是由一组相关的Task组成的,这些Task可以并行执行,且它们之间存在依赖关系。Spark应用程序中的每个Action操作都会生成一个Job。 7. Stage:阶段,是Spark作业中的一个任务划分单元,是由若干个Task组成的。Spark会将一个Job划分成多个Stage,以便进行并行计算。一个Stage中的所有Task都可以并行执行,但是它们之间存在着依赖关系。Spark将具有相同的计算依赖关系的Task划分为同一个Stage

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值