2.1.2、RDD
2.1.2.1 Feature
![](https://i-blog.csdnimg.cn/blog_migrate/ff0c9eadfc48b8c1473f098b45964c4e.png)
1、可分区
RDD是可以被分区的,每一个分区被一个Task处理,分区数决定了并行度,并行度默认从父RDD传递给子RDD。
默认情况下,HDFS上的一个数据块就是一个分区。
2、存储位置信息(即优选位置)
每个RDD都会有一个优先位置列表,用来存储每个分区的优先位置
3、存储依赖列表
RDD每次转换都会生成新的RDD,所以RDD之间会形成依赖关系,对于这种关系,RDD会进行存储,这样当发生错误的时候可以从上一个RDD中进行恢复,这样保证了容错,对于RDD的容错又分为了几种情况。
DAG层面
即当Stage输出失败的时候,那么DAGScheduler就会进行重试
Task层面
当内部的task失败时,会根据底层的调度器进行重试
当然对于RDD之间的依赖类型又分为窄依赖和宽依赖,主要区别在于是否会发生shuffle。
窄依赖:父RDD的一个分区最多只能被一个子RDD的一个分区使用
宽依赖:父RDD的一个分区可以被多个子RDD的分区依赖;如groupByKey、SortBykey算子
4、分区器
分区器的使用只针对于KV类型的RDD,也就是说对于非KV类型的RDD没有具体的分区器。对于分区器的分配策略,目前有两种:
两种策略:
1.1、Hash
1.2、Range
5、可计算
每个RDD是有一个compute函数,并且是以分片为基本单位执行具体的业务逻辑进行计算的。
![](https://i-blog.csdnimg.cn/blog_migrate/d3dddac2c831d4bcdc4133b9b910fb4a.png)
2.1.3、Partition
2.1.3.1、coalesce
重分区,默认不进行shuffle。至于是否要进行shuffle,要根据具体 场景分析:
1、如果源分区数S>目标分区数T,则一般不会进行shuffle。比如从1000个分区数进行重新分配到100个分区,那么就不会发生shuffle。
2、如果源分区数S>目标分区数T,且是一种极端的合并,比如从1000个分区数进行重新分配到几个分区,那么这个时候可能会造成运行节点IO异常甚至OOM,所以为了避免这种情况发生,可以设置shuffle=true
3、如果源分区数S<目标分区数T,那么这个需要分两种情况:
3.1、当设置shuffle=false时候不会发生shuffle,最后得到S个分区。比如从100个分区重复分配到1000个分区,最后得到100个分区
3.2、当设置shuffle=true时会发生shuffle,最后得到T个分区。比如从100个分区重复分配到1000个分区,最后得到1000个分区
![](https://i-blog.csdnimg.cn/blog_migrate/5646917d349128fff80d39c616a05baa.png)
2.1.3.2、repartition
![](https://i-blog.csdnimg.cn/blog_migrate/646c0ed66df6fc5eecd20847a407ec38.png)
repartition可以增加或者减少RDD并行度。底层其实调用的就是coalesce(numPartitions,shuffle=true),使用hash随机分区;
所以在使用repartition的时候,一定会发生shuffle的。
因此如果要减少分区数的时候,使用coalesce(shuffle=false)会避免shuffle发生。