RDD(resilient dastributed dataset)
RDD:弹性分布式数据集。所谓“弹性”,可以自动进行内存和磁盘的切换;具有高效容错、任务失败充实等特点;一个RDD可进行多个分区;RDD分区之间存在依赖关系,分为“宽依赖”和“窄依赖”,前者是指一个父RDD分区被多个子RDD分区所使用,后者是指一个父RDD分区最多被一个子RDD分区多使用
2大创建:
-
Parallelized Collections
将已经存在的数据集转化成rdd/其他RDD转化形成新的RDD,一般在进行测试的时候使用
#sc即SparkContext val data = Array(1,2,3,4,5) #第二个参数10是手动创建的partitions,可选参数 val rdd = sc.parallelize(data,10)
-
External Datasets
由外部存储系统的数据集创建,包括本地的文件系统,还有所有Hadoop支持的数据集,比如HDFS、HBase。
#URI(Uniform Resource Identifier,统一资源标识符),而URL(URL:Uniform Resource Location统一资源定位符),URL是URI的子集 #参数是文件的URI(file///,还可以是hdfs://,) val distFile = sc.textFile("data.txt") distFile: org.apache.spark.rdd.RDD[String] = data.txt MapPartitionsRDD[10] at textFile at <console>:26
5大特性
<!--源码中的描述-->
* - A list of partitions
* - A function for computing each split
* - A list of dependencies on other RDDs
* - Optionally, a Partitioner for key-value RDDs (e.g. to say that the RDD is hash-partitioned)
* - Optionally, a list of preferred locations to compute each split on (e.g. block locations for an HDFS file)
-
一组分片(Partition),即数据集的基本组成单位。 对于RDD来说,每个分片都会被一个计算任务处理,并决定并行计算的粒度。用户可以在创建RDD 的时候指定RDD的分片个数,如果没有指定,那么就会采用默认值。默认值就是程序所分配到的CPU Cores 的数目;
-
对于RDD来说,每个分片都会被一个计算任务处理,并决定并行计算的粒度。Spark中RDD的计算是以分片为单位的,每个RDD都会实现compute函数以达到这个目的。compute函数会对迭代器进行复合,不需要保存每次计算的结果;
-
RDD 之间互相存在依赖关系。 RDD 的每次转换都会生成一个新的 RDD ,所以 RDD 之间就会形成类似于流水线一样的前后依赖关系。在部分分区数据丢失时,Spark 可以通过这个依赖关系重新计算丢失部分的分区数据,而不是对 RDD 的所有分区进行重新计算。—具有容错性
-
一个Partitioner ,即 RDD 的分片函数 。当前Spark 中实现了两种类型的分片函数,一个是基于哈希的 HashPartitioner ,另外一个是基于范围的 RangePartitioner。只有对于key-value的RDD ,才会有 Partitioner,非 key-value 的RDD 的 Partitioner 的值是None。Partitioner 函数不但决定了RDD 本身的分片数量,也决定了 Parent RDD Shuffle 输出时的分片数量。
-
一个列表,存储存取每个Partition 的优先位置(preferred location)。 对于一个HDFS 文件来说,这个列表保存的就是每个 Partition 所在的块位置。根据**“移动数据不如移动计算”**的理念,Spark 在进行任务调度的时候,会尽可能地将计算任务分配到其所要处理数据块的存储位置。
3大算子:
transformations:数据内容不会变化,形式改变,懒加载,只有在actions阶段才执行。
操作 | 含义 |
---|---|
map(func) | 返回一个新的RDD,该RDD由每一个输入元素经func函数转换后组成 |
filter(func) | 返回一个新的RDD,该RDD由经过func函数计算后返回值为true的输入元素组成 |
flatMap(func) | 类似于map,但是每一个输入元素可以被映射为0或多个输出元素(所以func应该返回一个序列,而不是单一元素) |
repartition(numPartitions) | 重新分区 |
join(otherDataset, [numTasks]) | 在类型为(K,V)和(K,W)的RDD上调用,返回一个相同key对应的所有元素对在一起的(K,(V,W))的RDD 相当于内连接(求交集) |
sample(withReplacement, fraction, seed) | 根据fraction指定的比例对数据进行采样,可以选择是否使用随机数进行替换,seed用于指定随机数生成器种子 |
union(otherDataset) | 对源RDD和参数RDD求并集后返回一个新的RDD |
intersection(otherDataset) | 对源RDD和参数RDD求交集后返回一个新的RDD |
distinct([numTasks])) | 对源RDD进行去重后返回一个新的RDD |
groupByKey([numTasks]) | 在一个(K,V)的RDD上调用,返回一个(K, Iterator[V])的RDD |
reduceByKey(func, [numTasks]) | 在一个(K,V)的RDD上调用,返回一个(K,V)的RDD,使用指定的reduce函数,将相同key的值聚合到一起,与groupByKey类似,reduce任务的个数可以通过第二个可选的参数来设置 |
sortByKey([ascending], [numTasks]) | 在一个(K,V)的RDD上调用,K必须实现Ordered接口,返回一个按照key进行排序的(K,V)的RDD |
sortBy(func,[ascending], [numTasks]) | 与sortByKey类似,但是更灵活 第一个参数是根据什么排序 第二个是怎么排序 false倒序 第三个排序后分区数 默认与原RDD一样 |
cogroup(otherDataset, [numTasks]) | 在类型为(K,V)和(K,W)的RDD上调用,返回一个(K,(Iterable,Iterable))类型的RDD |
actions:
操作 | 含义 |
---|---|
reduce(func) | 通过func函数聚集RDD中的所有元素,这个功能必须是可交换且可并联的 |
collect() | 以数组的形式返回数据集的所有元素 |
count() | 返回RDD的元素个数 |
first() | 返回RDD的第一个元素 |
take(n) | 返回一个由数据集的前n个元素组成的数组 |
saveAsTextFile(path) | 将数据集的元素以textfile的形式保存到HDFS文件系统或者其他支持的文件系统,对于每个元素,Spark将会调用toString方法,将它装换为文件中的文本 |
countByKey() | 针对(K,V)类型的RDD,返回一个(K,Int)的map,表示每一个key对应的元素个数 |
foreach(func) | 在数据集的每一个元素上,运行函数func进行更新 |
lookup | 对<key,value>型的rdd操作,返回指定key对应的元素形成的seq。如果这个rdd包含分区器,那么只扫描对应key所在的分区,若不含,则进行全盘扫描 |
controller:
操作 | 含义 |
---|---|
cache | 只有一个默认的缓存级别MeMORY-ONLY,cache调用了persist |
persist | 可以根据情况设置其缓存级别 |
用处: | 两者都是用来将一个RDD进行缓存的,避免重复计算,从而节省程序运行的时间。 |