一、RDD的基本概念
- RDD ,弹性分布式数据集, 是分布式内存的一个抽象概念,是Spark中最为基本也最为重要的一个抽象,如果说Java的哲学是“万物皆对象”的话,可以笼统地认为Spark的哲学是“万物皆RDD”,这句话的意思是在Spark中无论何种数据源输入后都最终转为RDD,然后对RDD进行各种运算,这也是Spark的统一性。RDD提供了一种高度受限的共享内存模型,即RDD是只读的记录分区的集合,只能通过在其他RDD执行确定的转换操作(如map、join和flatMap)而创建,然而这些限制使得实现容错的开销很低。
- RDD具有如下特征
(1).一个分区列表。 即待处理的数据会被Spark根据某种算法进行分块,每个块其实就是一个分区。比如说数据源是HDFS,那么会根据数据的在HDFS上的块数进行分区,有多少块就多少区。RDD会维护一份这样的分区列表。
(2).一个计算方法,用于计算每一个数据分区。 其实计算方法本质上就是我们的处理逻辑,我们调用各种算子对RDD进行操作,RDD会把这个过程记录下来。
(3).一个 RDD 的依赖列表。 RDD是只读的,每对一个RDD进行transform操作就会产生新的RDD,新的RDD就会和旧的RDD产生依赖关系,即旧的RDD是新的RDD的父亲,也称旧RDD为新RDD的父RDD,这就是RDD的依赖。而RDD会维护一份这样的依赖以便于容错。
(4).一个 Partitioner(分区器),对于键值对 RDD,此项可选。
(5).一个数据分区计算的首选位置列表( 例如,用于 Hadoop 分布式文件系统[HDFS]文件的块位置。 ) ,此项可选。 这和数据本地化有关,假设Spark的工作节点即Worker Node要处理HDFS上的数据,那么Spark会优先选择在对应Hadoop集群上的Datanode主机上处理存储在该DataNode节点上的要处理的数据,以达到将网络数据传输降到最低的目标。
- 简而言之,RDD虽然叫弹性分布式数据集,但是其本身是不存储任何要处理的数据的,因此RDD是一种轻量级的抽象。可以这样理解RDD,它就像是一张纸,上面记录了待处理数据源的分区信息,保存了如何操作这些数据(计算方法),维护了一份RDD之间的依赖关系表等等,等到要计算时,这张“纸”会被分发到每一个要工作的“人”,即Worker节点那里,然后每个“人”通过查阅这张纸知道了自己要处理哪个分区(分区列表),怎么做(计算方法)等等。因此,RDD作为数据结构,本质上是一个只读的分区记录集合。一个RDD可以包含多个分区,每个分区就是一个dataset片段。RDD可以相互依赖。
二、创建RDD
1.使用三种方式创建RDD
- 使用SparkContext的parallelize()方法序列化本地数据集合创建RDD。
- 使用外界的数据源创建RDD,比如说本地文件系统,分布式文件系统HDFS等等。
- 通过将已有RDD使用transform算子操作产生新的RDD。
2.使用Java演示三种方式创建RDD
public class CreateRDDJava {
public static void main(String[] args) {
SparkConf conf = new SparkConf()
.setAppName("CreateRDDJava")
.setMaster("local")
JavaSparkContext sc = new JavaSparkContext(conf)