1. RDD常用转换算子
1) map(f:T => U)
2) filter(f:T => Bool) // 过滤操作
3) flatMap(f:T => Seq[U]) // 将RDD中的每个集合合并成新的更大的集合
4) glom() // 将每个分区中的元素组成一个数组
5) distinct() // 将每个分区中的元素进行去重
6) cartesain() // 对RDD中每个数据集中的元素做笛卡尔集
7) union() // 将两个RDD中的元素合并到一个RDD中
8) mapValues() // 仅对集合元素是K-V类型中的value进行操作
9) subtract() // 去掉两个RDD中相同的元素
10) sample() // 对RDD以指定采样百分比进行采样
11) takeSample() // 和Sample类似,但直接返回结果而不是RDD
12) groupBy() // 按key值对元素进行分类
13) reduceByKey() // 根据key值进行操作
2. RDD的操作类型
1) transformation //转换
从已经存在的数据集中创建一个新的数据集
transformation操作都具有lazy特性,Spark不会进行实际的操作,而是记录操作的轨迹,只有执行action时才会进行真正的计算(有利于高效性和Spark根据DAG图进行算子合并)
2) action //动作
在数据集上计算后返回结果到Driver
** 默认的情况下,每个动作在执行时会将之前的数据重新计算一遍,但是为了保证计算的高效性和计算结果的重用性,可以在特定的计算环节上进行Persist(或cache)方法将计算结果持久化到内存或磁盘,提高整体的计算效率。
3. RDD底层实现原理
1)RDD是一个被并行计算的、不可变的、分片的元素集合
2)在内部,RDD都有5个重要的特征:
一个分区列表
一个计算每个分片的函数
其他RDD一系列依赖
一个键值RDDS分区
一组计算分区的优先位置
3)RDD抽象接口包含的一些基本操作
partitions() // 返回一组Partitions对象
preferredLocations(p) // 根据数据存放的位置,返回分区p在哪节点访问更快
dependencies() // 返回一组依赖
iterator(p, parentlters) // 按照父分区的迭代器,逐个计算分区p的元素
partitioner() // 返回RDD是否hash/range分区的元数据信息
4. RDD的并行度
1)RDD创建时会默认划分多个分区,在Spark进行任务调度时会为每一个分区创建一个任务
2)RDD会尝试根据集群的状况(如集群中底层存储系统的并行度,HDFS上存储的文件区块)来设置分区的数目
3)默认情况下,子RDD的分区会根据父RDD的分区决定
5. RDD的弹性特性
RDD被称为弹性数据集,主要体现在以下几个方面:
1. 自动进行内存和磁盘数据存储的切换,默认在内存中,内存放下时就会放入磁盘中,前提是持久化级别设置为MEMORY_AND_DISK
2. 基于lineage(血统)的高效容错,当计算步骤很多,如果某个环境出错,他会从指定位置恢复数据。可恢复的前提是该位置已经进行了计算结果数据的持久化
3. Task任务失败会进行特定次数的重试
4. stage失败会进行特定次数的重试,且只计算失败的分片
5. cheakpoint(检查点)和persist(持久化),把某些需要经常访问的数据持久化到内存
6. 数据调度,DAG Task和资源管理无关,Spark集群中任务调度和资源调度使分开的
7. 数据分片的高度:分片过少会造成分片过大,从而使某个节点产生OOM;若分片过多,导致文件频繁读取,单位时间内资源利用率不高。