RDD简介
RDD,全称为Resilient Distributed Datasets(弹性分布式数据集),是一个容错的、并行的数据结构,可以让用户显式地将数据存储到磁盘和内存中,并能控制数据的分区。同时,RDD还提供了一组丰富的操作来操作这些数据。在这些操作中,诸如map、flatMap、filter等转换操作实现了函数式编程模式,很好地契合了Scala的集合操作。除此之外,RDD还提供了诸如join、groupBy、reduceByKey等更为方便的操作(注意,reduceByKey是action,而非transformation),以支持常见的数据运算。
通常来讲,针对数据处理有几种常见模型,包括:Iterative Algorithms,Relational Queries,MapReduce,Stream Processing。例如Hadoop MapReduce采用了MapReduces模型,Storm则采用了Stream Processing模型。RDD混合了这四种模型,使得Spark可以应用于各种大数据处理场景。
定义: 只读的,可分区的分布式数据集;数据集可全部或部分缓存在内存中,在一个App多次计算间重用, RDD是Spark的核心。
血统容错:根据血统(父子间依赖关系)重计算恢复丢失数据
RDD操作: Transformation算子和Action算子。
原生数据空间转RDD
原生的SCALA数据集合可以转换为RDD进行操作
包含一下两种方式
makeRDD
parallelize
存储文件转RDD
Partition(分区)
一份待处理的原始数据会被按照相应的逻辑切分成n份,每份数据对应到RDD中的一个Partition,Partition的数量决定了task的数量,影响着程序的并行度,所以理解Partition是了解spark背后运行原理的第一步。
分区数的设置:
- 在local模式下通过设置local[*],设置分区数
local[2]:2个
local[*]:拿到当前CPU的内核数,比如是双核的就是2 4核就是4
- 通过自定义分区数
- 通过设置初始化分区数
sc.makeRDD(1 to 1000,5)
- 可通过算子来进行修改分区数.repartition(3)
- 如果使用的是scala集合的话,在特定的格式下,会根据数量量来创建分区makeRdd
- 读取HDFS上的数据时根据块的数量来划分分区数
Spark核心概念 – 宽依赖和窄依赖
RDD父子依赖关系:窄( Narrow)依赖和宽( Wide)依赖。
窄依赖:指父RDD的每一个分区最多被一个子RDD的分区所用。
宽依赖:指子RDD的分区依赖于父RDD的所有分区。
Stage:
一个Job会被拆分为多组Task,每组任务被称为一个Stage就像Map Stage, Reduce Stage。Stage的划分在RDD的论文中有详细的介绍,简单的说是以shuffle和result这两种类型来划分。在Spark中有两类task,一类是shuffleMapTask,一类是resultTask,第一类task的输出是shuffle所需数据,第二类task的输出是result,stage的划分也以此为依据,shuffle之前的所有变换是一个stage,shuffle之后的操作是另一个stage。比如 rdd.parallize(1 to 10).foreach(println) 这个操作没有shuffle,直接就输出了,那么只有它的task是resultTask,stage也只有一个;如果是rdd.map(x => (x, 1)).reduceByKey(_ + _).foreach(println), 这个job因为有reduce,所以有一个shuffle过程,那么reduceByKey之前的是一个stage,执行shuffleMapTask,输出shuffle所需的数据,reduceByKey到最后是一个stage,直接就输出结果了。如果job中有多次shuffle,那么每个shuffle之前都是一个stage.