一、Spark RDD概念
1、简单的解释
RDD是将数据项拆分为多个分区的集合,存储在集群的工作节点上的内存中,并执行正确的操作
2、复杂的解释
- RDD是用于数据转换的接口
- RDD指向了存储在HDFS、Cassandra、HBase等、或缓存(内存、内存+磁盘、仅磁盘等),或在故障或缓存收回时重新计算其他RDD分区中的数据
3、RDD是弹性分布式数据集
(1)分布式数据集
- RDD是只读的、分区记录的集合,每个分区分布在集群的不同节点上
- RDD并不存储真正的数据,只是对数据和操作的描述
(2)弹性
- RDD默认存放在内存中,当内存不足,Spark自动将RDD写入磁盘
(3)容错性
- 根据数据血统,可以自动从节点失败中恢复分区
二、Spark RDD特点
1、RDD与DAG
- 两者是Spark提供的核心抽象
- DAG(有向无环图)反映了RDD之间的依赖关系
2、RDD的特性
- 一系列的分区(分片)信息,每个任务处理一个分区
- 每个分区上都有 compute 函数,计算该分区中的数据
- RDD之间有一系列的依赖
- 分区函数决定数据(key-value)分配至哪个分区
- 最佳位置列表,将计算任务分派到其所在处理数据块的存储位置
3、RDD编程流程
![](https://i-blog.csdnimg.cn/blog_migrate/d72e5ec426521859d716e1d67c92228f.png)
三、Spark RDD的创建
1、使用IDEA初始化Spark运行环境
(1)创建Maven
项目,添加如下依赖
- scala-library
- spark-core
- spark-sql
<dependency>
<groupId>org.scala-lang</groupId>
<artifactId>scala-library</artifactId>
<version>2.11.8</version>
</dependency>
<dependency>
<groupId>org.apache.spark</groupId>
<artifactId>spark-sql_2.11</artifactId>
<version>2.1.1</version>
</dependency>
<dependency>
<groupId>org.apache.spark</groupId>
<artifactId>spark-core_2.11</artifactId>
<version>2.1.1</version>
</dependency>
(2)创建SparkContext
//方式一
import org.apache.spark.{SparkConf, SparkContext}
val conf = new SparkConf().setAppName("actionadddemo").setMaster("local[*]")
val sc = new SparkContext(conf)
//方式二
import org.apache.spark.{SparkConf, SparkContext}
val conf = new SparkConf().setAppName("actionadddemo").setMaster("local[*]")
val sc=SparkContext.getOrCreate(conf)
(3)创建SparkSession
import org.apache.spark.sql.SparkSession
val spark = SparkSession.builder.master("local[2]").appName("appName").getOrCreate()
2、RDD的创建
(1)使用集合创建RDD
- Spark默认会根据集群的情况来设置分区的数量,也可以通过parallelize()第二参数来指定
- Spark会为每一个分区运行一个任务进行处理
//parallelize创建
val rdd1=sc.parallelize(List(1,2,3,4,5,6))
rdd1.count
rdd1.partitions.size //分区数
val rdd2=sc.parallelize(List(1,2,3,4,5,6),5)
rdd2.partitions.size
//makeRDD创建
val rdd3=sc.makeRDD(List(1,2,3,4,5,6))
(2)通过加载文件创建RDD
- 文件中的一行文本作为RDD的一个元素
- Spark默认访问HDFS
- Spark默认为HDFS文件的每一个数据块创建一个分区,也可以通过textFile()第二个参数指定,但只能比数据块数量多
val distFile=sc.textFile("file:///home/hadoop/data/hello.txt")
distFile.count
val distHDFSFile=sc.textFile("hdfs://hostname:9000/hello.txt")
sc.textFile("/my/directory/")
sc.textFile("/my/directory/*.txt")
3、RDD分区
分区是RDD被拆分并发送到节点的不同块之一
- 我们拥有的分区越多,得到的并行性就越强
- 每个分区都是被分发到不同Worker Node的候选者
- 每个分区对应一个Task
4、RDD的操作
分为lazy
与non-lazy
两种
- Transformation(lazy):也称转换操作、转换算子
- Actions(non-lazy):立即执行,也称动作操作、动作算子
(1)RDD转换算子
- 对于转换操作,RDD的所有转换都不会直接计算结果
- 仅记录作用于RDD上的操作
- 当遇到动作算子(Action)时才会进行真正计算
(2)RDD动作算子
- 本质上动作算子通过SparkContext执行提交作业操作,触发RDD DAG(有向无环图)的执行
- 所有的动作算子都是急迫型(non-lazy),RDD遇到Action就会立即计算