Spark RDD及编程接口

版权声明:本文为博主原创文章,转载请标明出处。 https://blog.csdn.net/Smart_cxr/article/details/88675284

1.介绍

对于一个Spark程序而言,一般情况下RDD操作之间的关系图如下所示,经过输入(创建)操作,转换操作,输出操作(action操作)来完成一个作业。

2.Spark RDD

RDD是弹性分布式数据集,即一个RDD代表了一个被分区的只读数据集,RDD可以通过两种方式生成,一种是来自内部或者外部的存储系统另一种是通过转换操作(transform)来自其他的RDD,比如Map、filter、join等。开发者可以对RDD进行另外两个方面的操作:持久化和分区。一般情况下抽象的RDD需要包含以下五个特性(接口):

2.1 RDD分区

对于一个RDD而言分区的多少涉及对这个RDD进行并行计算的粒度,每一个RDD分区的计算都在一个单独的任务中被执行。用户可以自行指定分区数,如果没有指定则会使用默认值。可以用以下方式来进行查看分区数

当然在创建RDD的时候也可以不指定分区,这时候会采用系统的默认分区,分区数是这个程序所分配到的资源的CPU核的个数。

2.2 RDD的优先位置

RDD的优先位置与Spark的调度有关,在Spark进行任务调度的时候,尽可能的将任务分配到数据块所存储的位置。

2.3 RDD的依赖关系

RDD中有两种依赖,一种是宽依赖,另一种是窄依赖。

宽依赖:每一个父RDD最多只被子RDD的一个分区所使用。

窄依赖:多个子RDD的分区会依赖与同一个父RDD的分区。

2.3 RDD的分区计算

Spark中的RDD计算都是以partition(分区)为单位的,而RDD中的compute函数都是在对迭代器进行复合,不需要保存每次计算的结果,由于compute函数只返回相应分区数据的迭代器,所以只有在最终实例化的时候才能显示出两个分区的最终计算结果。

2.4 RDD的分区函数

partitioner就是RDD的分区函数,目前Spark包含了两种的分区函数,一种是哈希分区(HashPatitioner),一种是区域分区(RangePatitioner)

详情参考https://blog.csdn.net/dmy1115143060/article/details/82620715

2.5 创建操作

RDD的形成可以由内部集合类型来生成,也可以从外部存储的数据进行生成。

2.6 转换操作

基本的转换操作有:map、distinct、flatmap。repartition和coalesce是对RDD的分区进行重新分区,reparation只是对coalesce接口中shuffle为true的简易实现。假设RDD有N个分区,需要重新划分成M个分区。

①如果N<M,一般情况下N个分区有数据分区不均的状况,利用HashPartitioner函数将数据进行重新的分区为M个,这是需要将shuffle参数设置为true。

②如果N>M且N和M相差不多,那么就可以将N个分区的若干个分区合并成一个新的分区,最终合并成M个分区,这是可以将shuffle参数设置为false。(shuffle为false的情况下,设置M>N coalesce是不起作用的)不进行shuffle操作,父子RDD是窄依赖的关系。

③如果N>M且N和M相差悬殊,将shuffle设置为true,可以有更好的并行度。

在这里介绍一下combineByKey这个接口的内部实现其实是分为三步来完成的,首先根据是否需要在Map端进行combine操作决定是否对RDD先进行一次mapPartition操作(利用createCombiner、mergeValue、mergeCombiner三个函数)来达到减小shuffle数据量的作用。第二步根据partitioner函数对MapPartitionRDD进行shuffle操作。最后对与shuffle的结构再进行一次combine操作。原理图如下:

2.7 控制操作

cache、persist是两个对RDD进行持久化操作的函数,可以将RDD持久化到不同存储介质中,以便于重复利用。checkpoint接口是将RDD持久化到HDFS中,与persist不同的是,checkpoint会切断此RDD之前的依赖关系而persist依然保留着依赖关系cache与persist的唯一区别在于: cache只有一个默认的缓存级别MEMORY_ONLY ,而persist可以根据StorageLevel设置其它的缓存级别。cache的底层实现其实就是persist。

2.8 action操作

如:collect、count、reduce等。

展开阅读全文

没有更多推荐了,返回首页