什么是RDD
RDD叫做弹性分布式数据集,Spark进行计算的数据容器,RDD的来源可以是HDFS
RDD特性
只读:不能修改,只能通过转换操作生成新的RDD
基于内存:
弹性:计算过程中内存不够时
分布式:可以分布在多台机器上进行处理
数据集:用于Spark计算的数据源的数据封装
声明RDD
import org.apache.spark.rdd.RDD //导入RDD类
val a1 : Array[Int] = Array(1, 2, 3) //声明一个数组
val r1 : RDD[Int] = sc.parallelize(a1) //将a1 数组变为RDD
r1.collect() //查看r1 数据
RDD分区
分区目的:为了并行计算
每个RDD可以分成多个分区,每个分区就是一个数据集片段
分区是RDD内部并行计算的一个计算单元
分区的格式决定了计算的粒度
而每个分区的数值计算都是在一个任务中进行
因此任务个数,也由RDD的分区决定
分区原则
RDD分区的个数尽量等于集群中CPU的数量
分区过多并不会增加执行速度
例:集群中有10内核
分5个区,浪费5个内核
分20个区,会有10个分区等待
创建分区
val pa1 : Array[Int] = Array(1, 2, 3, 4, 5) //创建一个数组
val pr1 : RDD[Int] = sc.parallelize(pa1, 5) //将pa1 数组分成5个区
pr1.partitions.size //查看分区数
RDD血统
RDD通过Lineage(血统)实现数据的容错性
RDD依赖
RDD通过操作算子进行转换,转换得到的新RDD包含了从其他RDD衍生所必需的信息
依赖包括两种,窄依赖、宽依赖:宽窄针对的是分区的数据,不是分区数量
窄依赖:收窄
每个父RDD的一个分区最多被子RDD的一个分区使用(1:1、n:1)
父RDD的分区不会放到不同的子RDD分区
宽依赖:放宽
一个父RDD分区会被多个子RDD分区使用
子RDD的数据分区时,数据会有一定的交叉
区分宽依赖和窄依赖不能通过父RDD与子RDD分区的比值,要看数据是否出现交叉
Stage划分原则:将宽依赖前的窄依赖划分为一个Stage
RDD持久化
保存RDD中间结果