RDD的特点
图中展示的是textFile方法读取文件来创建RDD。
RDD要从两个方面考量:1.实现的功能 2.如何进行分区
- 每一个RDD的计算功能是不同的,所以RDD称之为最小的计算单元
- RDD的计算是分布式的,RDD封装了计算逻辑,那么接下来如何将数据分配给不同的Executor做分布式计算,这就是分区的目的
RDD代表一个弹性的、不可变、可分区、里面的元素可并行计算的集合
-
RDD在底层原码中就是一个抽象类
-
弹性
1.存储的弹性:内存与磁盘的自动切换;Spark的计算是基于内存的,但是内存是有限的,在某些情况下可以将数据放在磁盘。
2.容错的弹性:数据丢失可以自动恢复;根据RDD的血缘关系可以追踪到数据源,所以数据丢失问题不大
3.计算的弹性:计算出错重试机制;计算出错,可以从头重新计算
4.分片的弹性:可根据需要重新分片。分片就是分区,可以根据需要重新分区,比如有四个Executor,但是上一层RDD只有两个分区,那么可以在当前RDD重新指定分区个数,更合理的利用资源 -
分布式
数据存储在大数据集群不同节点上。数据的存储和计算都在分布式集群中 -
数据集
RDD封装了计算逻辑,并不保存数据。 -
数据抽象
RDD是一个抽象类,需要子类具体实现 -
不可变
RDD封装了计算逻辑,是不可以改变的,想要改变,只能产生新的RDD, -
可分区、并行计算
通过分区将数据分开交给不同的Executor,从而实现并行计算
RDD的五大核心属性
- RDD源码中对RDD的说明
(1)分区列表
RDD数据结构中存在分区列表,将数据进行分区,分区间的数据是完全相互独立的,互不影响,然后交给不同的Task,目的是实现并行计算,是实现分布式计算的重要属性。
(2)分区计算函数
Spark在计算时,是使用分区计算函数对每一个分区进行计算。但是,每一个分区计算函数的计算逻辑都是一样的,是由RDD事先封装好,传递到Executor的!
(3)RDD之间的依赖关系
- RDD是计算模型的封装,当需求中需要将多个计算模型进行组合时,就需要将多个RDD建立依赖关系。从方法中可以看出一个RDD的依赖是一个列表。
- 所谓的RDD依赖关系就是包装,想要获取最外层的RDD,就要逐层网内,从最原始的RDD开始构建。
以wordcount例子为例,每一个算子都会产生一个RDD,都是一层一层包装 - RDD不是单依赖,意味着可以多个RDD合成一个RDD
(4)分区器(可选)
- 分区器制定分区规则
- 当数据为KV类型数据时,可以通过设定分区器自定义数据的分区
##(5)首选位置(可选)
用于解决将task交给哪个Executor进行运算的问题。
- 当数据和Executor在一个节点的时候,Task首选分配给当前节点的Executor,这样避免了数据的网络传输,效率最优。
- 核心概念:移动数据不如移动计算 ;在有数据的节点上创建Executor进行计算
RDD执行原理
从计算的角度来讲,数据处理过程中需要计算资源(内存 & CPU)和计算模型(逻辑)。执行时,需要将计算资源和计算模型进行协调和整合
Spark框架在执行时,先申请资源;然后将应用程序的数据处理逻辑分解成一个一个的计算任务;然后将任务发到已经分配资源的计算节点上, 按照指定的计算模型进行数据计算。最后得到计算结果。
RDD是Spark框架中用于数据处理的核心模型,接下来我们看看,在Yarn环境中,RDD的工作原理
1.启动Yarn集群环境,此时有了资源
2.Spark通过申请资源创建调度节点和计算节点,也就是Driver和Executor,二者都是运行在NodeManager上
-
Spark框架根据需求将计算逻辑根据分区划分成不同的Task,并将Task放入TaskPool,放进任务池是为了等待被调度
-
调度节点(Driver)将任务根据计算节点Executor的状态 和 RDD首选位置的配置将Task发送到对应的计算节点进行计算
从以上流程可以看出RDD在整个流程中主要用于将逻辑进行封装,并生成Task发送给Executor节点执行计算,接下来我们就一起看看Spark框架中RDD是具体是如何进行数据处理的。



