分析一下rdd的特性和执行流程
- A list of partitions 存在一系列的分区列表
- A function for computing each split 每个rdd上面都存在compute方法进行计算
- 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) 在k-v类型的rdd上面存在可选的分区器
- Optionally, a list of preferred locations to compute each split on (e.g. block locations for an HDFS file) 优先位置进行计算
1. rdd的第一大特性:存在一系列的分区列表
每个rdd都存在一系列的分区列表,rdd弹性分布式数据集,必须是存在分区的,因为存在分区才会让集群多个线程进行执行,并行操作速度和效率更快。
分区可以进行调节,shuffle类算子可以修改分区,coalesce算子和repartition算子,修改分区在一定程度上可以增加计算效率,一个阶段中的一个rdd的分区代表的是一个task任务,并且在读取hdfs文件的时候,一个block块对应的是一个分区,让数据的计算本地化执行。
2. rdd的第二大特性:每个rdd上面都存在compute方法进行计算
rdd是调用算子进行计算的,一个元素一个元素的进行计算,compute帮助进行递归rdd的数据使用用户定义的逻辑进行计算。



我们compute方法是如何遍历RDD中的元素的。



如果是缓存了,那么从缓存中读取数据 getOrCompute

如果设置了缓存,并且已经有人计算完毕放入到缓存中了,那么直接从缓存中取值,如果缓存中没有值,我们需要计算并且存储到缓存中。

读取数据,如果命中就直接返回,如果没有命中就计算。

获取缓存数据

没有获取到数据需要进行计算,放入到缓存中,在从缓存中读取数据
doPutIterator
存储数据到缓存中,判断存储级别,分别放入数据到缓存或者磁盘中并且对数据进行备份和副本。
然后当放入完毕以后再次从缓存中读取数据。
3. rdd的第三大特性:每个rdd上面都存在一系列的依赖关系
rdd之间存在一系列的依赖关系。
所说的依赖关系就是rdd之间的关系,依赖关系就是算子的关系,转换类算子的关系,比如调用的算子不同关系也不相同。
map flatMap mapPartitions filter 一对一的关系,窄依赖
groupBy sortBy groupByKey sortByKey reduceBykey 他们都是带有shuffle的算子,都会产生宽依赖
shuffle就是宽依赖,非shuffle的算子就是窄依赖。

shuffleDependency:宽依赖
narrowDependency:窄依赖

窄依赖分为三种:
oneToOne 一个对一个的关系 map FlatMap filter...
rangeDependency: union范围依赖
pruneDependency: filterByRange 子类关系,父节点的部分数据被子节点继承了,排序完毕的结果被子节点继承一部分
宽依赖的关系

窄依赖的关系
map算子中的依赖关系

union算子

filterByRange

4. rdd的第四大特性:在kv类型的rdd上面存在可选的分区器。
首先rdd上面是不存在分区器的,只有调用了shuffle类算子才会有分区器 ,默认的分区器HashPartition[分组],rangePartitioner[排序]。
同样我们可以人为自定义分区器,但是不管是人为的还是系统自带的都需要在Key进行处理,需要实现两个方法:一个是分区的数量,numPartitions,一个是getPartition,怎么计算得到分区id。
不是kv类型的rdd肯定没有分区器,kv类型的rdd上面不一定存在分区器,分区器可以规定数据的流向,上游的数据到下游的相应的分区中是可以定义规则的
5. rdd的第五大特性:优先位置进行计算
一般数据的切片大小和block块的大小是一一对应的,可以实现本地化执行操作,避免了远程io。
读取hdfs的文件切片计算逻辑中就可以找到。

每次形成切片的时候都带有block的域名信息,处理和计算的时候就可以直接找到地址,按照本地化进行执行。