1、读入外部的数据源(或者内存中的集合)进行 RDD 创建;
2、RDD 经过一系列的 “转换” 操作,每一次都会产生不同的 RDD,供给下一个转换使用;
3、最后一个 RDD 经过 “行动” 操作进行处理,并输出指定的数据类型和值。
优点: 惰性调用、管道化、不需要保存中间结果。
RDD执行过程中的一个示例如下:
\quad \quad 如下图所示,在输入中逻辑上生成A和C两个RDD, 经过一系列"转换操作", 逻辑上生成"F"这个RDD, 之所以说是逻辑上, 是因为这个时候计算并没有发生. Spark只是记录了RDD之间的依赖关系. 当F要进行输出时, 就会执行"行动操作". Spark才会根据RDD的依赖关系生成DAG, 并从起点开始真正的计算.
\quad \quad 在Spark中,RDD被表示为对象,通过对象上的方法调用来对RDD进行转换。经过一系列的transformations定义RDD之后,就可以调用actions触发RDD的计算,action可以是向应用程序返回结果(count, collect等),或者是向存储系统保存数据(saveAsTextFile等)。 在Spark中,只有遇到action,才会执行RDD的计算(即延迟计算),这样在运行时可以通过管道的方式传输多个转换。
\quad \quad 要使用Spark,开发者需要编写一个Driver程序,它被提交到集群以调度运行Worker,如下图所示。Driver中定义了一个或多个RDD,并调用RDD上的action,Worker则执行RDD分区计算任务。
\quad \quad 在Spark中创建RDD的创建方式可以分为三种:从集合中创建RDD;从外部存储创建RDD;从其他RDD创建。
1、从集合中创建
\quad \quad 从集合中创建RDD,Spark主要提供了两种函数:parallelize
和makeRDD
1) 使用parallelize()从集合创建
scala> val rdd=sc.parallelize(Array(1,2,3,4))
rdd: org.apache.spark.rdd.RDD[Int] = ParallelCollectionRDD[199] at parallelize at <console>:26
2) 使用makeRDD()从集合创建
scala> val rdd1 = sc.makeRDD(Array(1,2,3,4,5,6,7,8))
rdd1: org.apache.spark.rdd.RDD[Int] = ParallelCollectionRDD[200] at makeRDD at <console>:26
scala> val rdd2 = sc.makeRDD(List(1,2,3,4,5,6,7,8))
rdd2: org.apache.spark.rdd.RDD[Int] = ParallelCollectionRDD[201] at makeRDD at <console>:26
2、由外部存储系统的数据集创建
\quad \quad 由外部存储系统的数据集创建,包括本地的文件系统,还有所有Hadoop支持的数据集,比如HDFS、Cassandra、HBase等
val rdd1=sc.textFile("文件路径")
3、从其他RDD创建
\quad \quad 通过对现有RDD的转换来创建RDD,常见的转换算子见算子这篇博文
比如:
val rdd2=rdd1.flatMap(_.split(" "))
\quad \quad 通过之前对RDD概念、依赖关系和阶段划分的介绍,结合之前介绍的Spark运行基本流程,总结一下RDD在Spark架构中的运行过程:
(1) 创建RDD对象
(2) SparkContext负责计算RDD之间的依赖关系,构建DAG
(3) DAGScheduler负责把DAG图分解成多个阶段,每个阶段中包含了多个任务,每个任务会被任务调度器分发给各个工作节点(Worker Node)上的Executor去执行