4、RDD 弹性分布式数据集
4-1、RDD的基本概念
弹性分布式数据集,本质上就是特殊的只读的分区记录集合,可以分成多个分区,每个分区就是一个数据集片段,分区可以保存在不同节点上进行计算。
4-2、RDD的特点
- a list of partitions:一个RDD是由多个partition组成的list,一般情况下,一个partition对应HDFS的一个block也就是一个文件
- a function for partiotioner:一个函数作用在每一个分区上,比如map的函数,每个分区都会执行一遍
- A list of dependencies on other RDDs:RDD之间有血缘依赖,可以分为窄依赖和宽依赖
- Optionally, a Partitioner for key-value RDDs (e.g. to say that the RDD is hash-partitioned):RDD内存的数据是key-value类型的,也就是说可以根据key进行重新hash分区
- Optionally, a list of preferred locations to compute each split on (e.g.block locations for an HDFS file):RDD具有数据本地性,也就是尽量靠近数据,(数据不动,代码动)
4-3、RDD的依赖关系
RDD的依赖关系可以分为窄依赖和宽依赖
- 窄依赖:一个父RDD的分区只能对应一个子RDD的分区
- 宽依赖:一个父RDD的分区可以对应多个RDD的多个分区
宽依赖一般会伴随shuffle操作
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fw5BdhGy-1624873370476)(pic\image-20200812195148915.png)][外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9k1mFj54-1624873421667)(pic\image-20200812195148915.png)]](https://i-blog.csdnimg.cn/blog_migrate/07e2288e9df44ff75b251d24b7774516.png)
宽窄依赖使得RDD有天生的容错性,并且窄依赖的恢复效率更高。
4-5、RDD的算子
RDD的算子可以分为Transformation算子和Action算子,其中Transformation算子时延迟计算的,只有遇到Action算子才会触发运算,Action算子会触发SparkContext 提交 Job 作业,进行计算。
Transformation算子如下:
| 算子名称 | 算子含义 |
|---|---|
| map(func) | 对RDD的每一条数据进行Map操作,最后返回新的RDD |
| filter(func) | 对RDD的每一条数据进行过滤,最后返回符合条件的新的RDD |
| flatMap(func) | 对RDD的每一条数据进行平铺Map操作,最后返回新的RDD |
| mapPartitions(func) | 对RDD的每一个分区进行操作,与Map区别在于它是一次加载分区的所有数据进行Map操作,每个分区只执行一次func,性能较高,但是对内存要去较高,最后与Map操作数据一致,最后返回新的RDD。 |
| union(other rdd) | 两个RDD进行并集操作,最后返回新的RDD |
| intersection(other rdd) | 两个RDD进行交集操作,最后返回新的RDD |
| distinct() | 对RDD进行去重,最后返回新的RDD |
| groupByKey() | 对RDD根据key进行分组,返回新的RDD,类型为(K, Iterator[V])的RDD,会产生shuffle |
| reduceByKey(func) | 对RDD根据key进行分组聚合操作,返回新的RDD,会产生shuffle |
| sortByKey() | 对RDD根据key进行排序,返回新的有序的RDD,会产生shuffle |
| sortBy(func) | 对RDD进行排序,可以自定义排序规则,返回新的有序的RDD,会产生shuffle |
| join(other rdd) | 两个RDD做连接,返回相同的key的RDD,格式为(K,(V,W)) |
| repartition() | 对RDD进行重分区操作,返回重分区后的RDD,会产生shuffle |
| cache() | 缓存当前的RDD到内存中,如果内存不够则只缓存一部分,当后续再调用时,不需要根据血缘从源头计算,类似于检查点 |
| persist() | 存储当前的RDD,与cache不一样的是,persist有多种存储策略,cache只是缓存到内存中,是persist的一种。 |
shuffle操作是进行重新分布数据的操作,这个过程需要大量读写磁盘,耗时相对较长,因此要尽量避免shuffle操作,如果避免不了,尽量采用更优的shuffle操作。
groupByKey()与reduceByKey(func)的区别:groupByKey()后面一般会跟上对数据操作的算子,比如map或filter,groupByKey()会直接将数据进行shuffle然后再操作,而reduceByKey会先在map阶段也就是节点本地先进行数据的combine合并可以自定义合并方式,这样就会减少shuffle数据传输的文件大小,性能更优。
groupByKey的示例图如下:

reduceByKey的示例图如下:

可以看出reduceByKey会在节点本地也就是shuffle前进行combine合并,这样在shuffle数据传输时,减少传输的文件,效率更高,因此,能用reduceByKey代替groupBykey就尽量代替,必须用的话就只能用groupByKey了。
Action算子如下:
| 算子名称 | 算子含义 |
|---|---|
| reduce(func) | 对RDD的所有数据进行自定义聚合操作,返回结果 |
| collect() | 以数组的形式返回当前RDD的所有元素 |
| first() | 返回当前RDD的第一个元素 |
| take(n) | 返回当前RDD的前n个元素 |
| aggregate() | 将RDD的所有数据进行相加,返回结果 |
| foreach(func) | 分别对RDD的每一个元素进行操作,没有返回值 |
| foreachPartition(func) | 分别对每一个分区进行操作,分区内还是对每一条数据进行操作,没有返回值 |
| saveAsTextFile(path) | 将每个元素通过toString转成文本保存在文本文件中 |
| saveAsSequenceFile() | 将RDD的元素以SequenceFile格式保存在文件中,对于HDFS,默认采用SequenceFile保存。 |
| saveAsObjectFile() | 将RDD的元素序列化后保存到文件中 |
本文介绍了弹性分布式数据集(RDD)的基本概念与特点,包括RDD的组成、依赖关系及算子分类,着重解析了Transformation与Action算子的功能及应用场景。
1081

被折叠的 条评论
为什么被折叠?



