Spark1.6学习-RDD

来源:互联网 发布:纳尼亚传奇知乎 编辑:程序博客网 时间:2024/05/05 08:14

最近开始学习spark的的东西,在学习之前可以去学习一些scala的,毕竟源码是scala的,有些东西操作习惯是从scala中扩展出来的。

下面切入正题

可以参考,下面的官方文档

http://spark.apache.org/docs/1.6.0/programming-guide.html#resilient-distributed-datasets-rdds

RDDs(Resilient Distributed Datasets

可以翻译成弹性分布式数据集合。

RDD是只读的、分区记录的集合。RDD只能基于在稳定物理存储中的数据集和其他已有的RDD上执行确定性操作来创建。这些确定性操作称之为转换,如map、filter、groupBy、join(转换不是程开发人员在RDD上执行的操作)。RDD作为数据结构,本质上是一个只读的分区记录集合。一个RDD可以包含多个分区,每个分区就是一个dataset片段。RDD可以相互依赖。如果RDD的每个分区最多只能被一个Child RDD的一个分区使用,则称之为narrow dependency;若多个Child RDD分区都可以依赖,则称之为wide dependency。

其实就是一种数据的分裂式的存储,将原来的一张大表,拆成小的多个组成部分,在使用时,可以重组起来进行操作,利用一些数据的局部化操作等。



Spark之所以将依赖分为narrow与wide,基于两点原因。

首先,narrow dependencies可以支持在同一个cluster node上以管道形式执行多条命令,例如在执行了map后,紧接着执行filter。相反,wide dependencies需要所有的父分区都是可用的,可能还需要调用类似MapReduce之类的操作进行跨节点传递。

其次,则是从失败恢复的角度考虑。narrow dependencies的失败恢复更有效,因为它只需要重新计算丢失的parent partition即可,而且可以并行地在不同节点进行重计算。而wide dependencies牵涉到RDD各级的多个Parent Partitions。下图说明了narrow dependencies与wide dependencies之间的区别:


本图来自Matei Zaharia撰写的论文An Architecture for Fast and General Data Processing on Large Clusters。图中,一个box代表一个RDD,一个带阴影的矩形框代表一个partition。

根据宽窄依赖进行stage的切分。

RDDs的操作分为两类:

1.是转换操作,就是从一种RDD->RDD ,一种RDD到另一种RDD只是做一种数据的转换。

2.是进行执行操作,就是action的,具体是在RDD上进行操作输出不是RDD的操作。

一般action会真实的触动整个job的执行,这个就是关于DAG的优化中所用到的一种,也就是再次体现了spark与stom的延迟性。


常用的数据转换操作有

1.Map

map是对RDD中的每个元素都执行一个指定的函数来产生一个新的RDD;RDD之间的元素是一对一关系

2.filter

Filter是对RDD元素进行过滤;返回一个新的数据集,是经过func函数后返回值为true的原元素组成; 

3.flatMap

flatMap类似于map,但是每一个输入元素,会被映射为0到多个输出元素(因此,func函数的返回值是一个Seq,而不是单一元素), RDD之间的元素是一对多关系; 

4.mapPartitions

mapPartitions是map的一个变种。map的输入函数是应用于RDD中每个元素,而mapPartitions的输入函数是每个分区的数据,也就是 把每个分区中的内容作为整体来处理的。

5.mapPartitionsWithIndex

mapPartitionsWithSplit与mapPartitions的功能类似, 只是多传入split index而已,所有func 函数必需是 (Int, Iterator<T>) => Iterator<U> 类型。

6.sample

sample(withReplacement,fraction,seed)是根据给定的随机种子seed,随机抽样出数量为frac的数据。withReplacement:是否放回抽 样;fraction:比例,0.1表示10% 

 7.union

union(otherDataset)是数据合并,返回一个新的数据集,由原数据集和otherDataset联合而成。

8.intersection

intersection(otherDataset)是数据交集,返回一个新的数据集,包含两个数据集的交集数据

9.distinct

distinct([numTasks]))是数据去重,返回一个数据集,是对两个数据集去除重复数据,numTasks参数是设置任务并行数量。 

10.groupByKey

groupByKey([numTasks])是数据分组操作,在一个由(K,V)对组成的数据集上调用,返回一个(K,Seq[V])对的数据集

11.reduceByKey

reduceByKey(func, [numTasks])是数据分组聚合操作,在一个(K,V)对的数据集上使用,返回一个(K,V)对的数据集,key相同的值, 都被使用指定的reduce函数聚合到一起

12.aggregateByKey

aggreateByKey(zeroValue: U)(seqOp: (U, T)=> U, combOp: (U, U) =>U) 和reduceByKey的不同在于,reduceByKey输入输出都是(K, V),而aggreateByKey输出是(K,U),可以不同于输入(K, V) ,aggreateByKey的三个参数:

 zeroValue: U,初始值,比如空列表{} ; 

seqOp: (U,T)=> U,seq操作符,描述如何将T合并入U,比如如何将item合并到列表 ;

 combOp: (U,U) =>U,comb操作符,描述如果合并两个U,比如合并两个列表 ; 

所以aggreateByKey可以看成更高抽象的,更灵活的reduce或group 

13.combineByKey

combineByKey是对RDD中的数据集按照Key进行聚合操作。聚合操作的逻辑是通过自定义函数提供给combineByKey。 

combineByKey[C](createCombiner: (V) ⇒ C, mergeValue: (C, V) ⇒ C, mergeCombiners: (C, C) ⇒ C, numPartitions: Int):RDD[(K, C)]把(K,V) 类型的RDD转换为(K,C)类型的RDD,C和V可以不一样。

14.sortByKey

sortByKey([ascending],[numTasks])是排序操作,对(K,V)类型的数据按照K进行排序,其中K需要实现Ordered方法。 

15.join

join(otherDataset, [numTasks])是连接操作,将输入数据集(K,V)和另外一个数据集(K,W)进行Join, 得到(K, (V,W));该操作是对于相同K 的V和W集合进行笛卡尔积 操作,也即V和W的所有组合; 

16.cogroup

cogroup(otherDataset, [numTasks])是将输入数据集(K, V)和另外一个数据集(K, W)进行cogroup,得到一个格式为(K, Seq[V], Seq[W]) 的数据集.

17.cartesian

cartesian(otherDataset)是做笛卡尔积:对于数据集T和U 进行笛卡尔积操作, 得到(T, U)格式的数据集


action操作

1.reduce

reduce(func)是对数据集的所有元素执行聚集(func)函数,该函数必须是可交换的。 

2.collect

collect是将数据集中的所有元素以一个array的形式返回。 

3.count

返回数据集中元素的个数。 

4.first

返回数据集中的第一个元素, 类似于take(1)。 

5.take

Take(n)返回一个包含数据集中前n个元素的数组, 当前该操作不能并行。

6.takeSample

takeSample(withReplacement,num, [seed])返回包含随机的num个元素的数组,和Sample不同,takeSample 是行动操作,所以返回 的是数组而不是RDD , 其中第一个参数withReplacement是抽样时是否放回,第二个参数num会精确指定抽样数,而不是比例

7.takeOrdered

takeOrdered(n, [ordering])是返回包含随机的n个元素的数组,按照顺序输出

8.saveAsTextFile

把数据集中的元素写到一个文本文件,Spark会对每个元素调用toString方法来把每个元素存成文本文件的一行。

9.countByKey

对于(K, V)类型的RDD. 返回一个(K, Int)的map, Int为K的个数

10.foreach

foreach(func)是对数据集中的每个元素都执行func函数.

0 0