千家信息网

Spark RDD算子分为哪几类

发表于:2026-11-02 作者:千家信息网编辑
千家信息网最后更新 2026年11月02日,本篇内容主要讲解"Spark RDD算子分为哪几类",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"Spark RDD算子分为哪几类"吧!RDD算子分类,大致
千家信息网最后更新 2026年11月02日Spark RDD算子分为哪几类

本篇内容主要讲解"Spark RDD算子分为哪几类",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"Spark RDD算子分为哪几类"吧!

RDD算子分类,大致可以分为两类,即:

1. Transformation:转换算子,这类转换并不触发提交作业,完成作业中间过程处理。

2. Action:行动算子,这类算子会触发SparkContext提交Job作业。

一:Transformation:转换算子

1. map:

将原来RDD的每个数据项通过map中的用户自定义函数f映射转变为一个新的元素。源码中map算子相当于初始化一个RDD,新RDD叫做MappedRDD(this,sc.clean(f) )。即:

map是对RDD中的每个元素都执行一个指定的函数来产生一个新的RDD。 任何原RDD中的元素在新RDD中都有且只有一个元素与之对应。

scala> val a = sc.parallelize(1 to 9, 3)a: org.apache.spark.rdd.RDD[Int] = ParallelCollectionRDD[6] at parallelize at :27scala> val b = a.map(x => x*3)b: org.apache.spark.rdd.RDD[Int] = MapPartitionsRDD[7] at map at :29scala> a.collectres7: Array[Int] = Array(1, 2, 3, 4, 5, 6, 7, 8, 9)                             scala> b.collectres8: Array[Int] = Array(3, 6, 9, 12, 15, 18, 21, 24, 27)

上述例子中把原RDD中每个元素都乘以3来产生一个新的RDD。

2. mapPartitions:

mapPartitions函数获取到每个分区的迭代器,在函数中通过这个分区整体的迭代器对整个分区的元素进行操作。内部实现是生成MapPartitionsRDD。

scala> val a = sc.parallelize(1 to 9, 3)a: org.apache.spark.rdd.RDD[Int] = ParallelCollectionRDD[10] at parallelize at :27scala> a.collectres11: Array[Int] = Array(1, 2, 3, 4, 5, 6, 7, 8, 9)                            scala> var c = a.mapPartitions( a=>a.filter(_>=7) )c: org.apache.spark.rdd.RDD[Int] = MapPartitionsRDD[11] at mapPartitions at :29scala> c.collectres12: Array[Int] = Array(7, 8, 9)

上述例子是通过函数filter对分区中所有数据进行过滤。

3. mapValues

针对(key,value)型数据中的Value进行操作,而不对Key进行处理。即:

mapValues顾名思义就是输入函数应用于RDD中Kev-Value的Value,原RDD中的Key保持不变,与新的Value一起组成新的RDD中的元素。因此,该函数只适用于元素为KV对的RDD。

scala> val a = sc.parallelize(List("Hadoop","HBase","Hive","Spark"), 2)a: org.apache.spark.rdd.RDD[String] = ParallelCollectionRDD[12] at parallelize at :27scala> val b = a.map(x => (x.length,x) )b: org.apache.spark.rdd.RDD[(Int, String)] = MapPartitionsRDD[13] at map at :29scala> b.mapValues(""+_+"").collectres14: Array[(Int, String)] = Array((6,Hadoop), (5,HBase), (4,Hive), (5,Spark))

4. mapWith:

mapWith是map的另外一个变种,map只需要一个输入函数,而mapWith有两个输入函数。

eg: 把partition index 乘以10,然后加上2作为新的RDD的元素.(3 是将十个数分为三个区)

scala> val x  = sc.parallelize(List(1,2,3,4,5,6,7,8,9,10),3)scala> x.mapWith( a => a*10 )( (a,b)=>(b+2)).collectres16: Array[Int] = Array(2, 2, 2, 12, 12, 12, 22, 22, 22, 22)

5. flatMap:

将原来RDD中的每个元素通过函数f转换为新的元素,并将生成的RDD的每个集合中的元素合并为一个集合,内部创建FlatMappedRDD(this,sc.clean() )。即:

与map类似,区别是原RDD中的元素经map处理后只能生成一个元素,而原RDD中的元素经flatmap处理后可生成多个元素来构建新RDD。

eg:对原RDD中的每个元素x产生y个元素(从1到y,y为元素x的值)。

scala> val a = sc.parallelize(1 to 4,2)scala> val b = a.flatMap(x => 1 to x )scala> a.collectres17: Array[Int] = Array(1, 2, 3, 4)                                           scala> b.collectres18: Array[Int] = Array(1, 1, 2, 1, 2, 3, 1, 2, 3, 4)

6. flatMapWith:

flatMapWith与mapWith很类似,都是接收两个函数,一个函数把partitionIndex作为输入,输出是一个新类型A;另外一个函数是以二元组(T,A)作为输入,输出为一个序列,这些序列里面的元素组成了新的RDD。

scala> val a = sc.parallelize(List(1,2,3,4,5,6,7,8,9),3)scala> a.collectres0: Array[Int] = Array(1, 2, 3, 4, 5, 6, 7, 8, 9)                             scala> a.flatMapWith(x => x,true)((x,y)=>List(y,x)).collectres1: Array[Int] = Array(0, 1, 0, 2, 0, 3, 1, 4, 1, 5, 1, 6, 2, 7, 2, 8, 2, 9)

7. flatMapWithValues:

flatMapValues类似于mapValues,不同的在于flatMapValues应用于元素为KV对的RDD中Value。每个一元素的Value被输入函数映射为一系列的值,然后这些值再与原RDD中的Key组成一系列新的KV对。

scala> val a = sc.parallelize( List((1,2),(3,4),(3,6)) )scala> a.collectres2: Array[(Int, Int)] = Array((1,2), (3,4), (3,6))scala> val b = a.flatMapValues( x => x.to(5))scala> b.collectres3: Array[(Int, Int)] = Array((1,2), (1,3), (1,4), (1,5), (3,4), (3,5))

上述例子中原RDD中每个元素的值被转换为一个序列(从其当前值到5),比如第一个KV对(1,2), 其值2被转换为2,3,4,5。然后其再与原KV对中Key组成一系列新的KV对(1,2),(1,3),(1,4),(1,5)。

8. reduce:

reduce将RDD中元素两两传递给输入函数,同时产生一个新的值,新产生的值与RDD中下一个元素再被传递给输入函数直到最后只有一个值为止。

eg:对元素求和。

scala> val a = sc.parallelize(1 to 10 )scala> a.reduce( (x,y) => x + y )res5: Int = 55

9. reduceByKey

顾名思义,reduceByKey就是对元素为KV对的RDD中Key相同的元素的Value进行reduce,因此,Key相同的多个元素的值被reduce为一个值,然后与原RDD中的Key组成一个新的KV对。

eg:对Key相同的元素的值求和,因此Key为3的两个元素被转为了(3,10)。

scala> val a = sc.parallelize(List((1,2),(3,4),(3,6)))scala> a.reduceByKey((x,y)=>x+y).collectres6: Array[(Int, Int)] = Array((1,2), (3,10))

10. cartesian:

对两个RDD内的所有元素进行笛卡尔积操作(耗内存),内部实现返回CartesianRDD。

scala> val a = sc.parallelize(List(1,2,3))scala> val b = sc.parallelize(List(4,5,6))scala> val c = a.cartesian(b)scala> c.collectres15: Array[(Int, Int)] = Array((1,4), (1,5), (1,6), (2,4), (3,4), (2,5), (2,6), (3,5), (3,6))

11. Sample:

sample将RDD这个集合内的元素进行采样,获取所有元素的子集。用户可以设定是否有有放回的抽样,百分比,随机种子,进而决定采样方式。

内部实现: SampledRDD(withReplacement,fraction,seed)。
函数参数设置:
‰ withReplacement=true,表示有放回的抽样。
‰ withReplacement=false,表示无放回的抽样。

根据fraction指定的比例,对数据进行采样,可以选择是否用随机数进行替换,seed用于指定随机数生成器种子。

scala> val a = sc.parallelize(1 to 100,3)scala> a.sample(false,0.1,0).countres16: Long = 12scala> a.sample(false,0.1,0).collectres17: Array[Int] = Array(10, 47, 55, 73, 76, 84, 87, 88, 91, 92, 95, 98)scala> a.sample(true,0.7,scala.util.Random.nextInt(10000)).countres19: Long = 75scala> a.sample(true,0.7,scala.util.Random.nextInt(10000)).collectres20: Array[Int] = Array(1, 3, 3, 3, 5, 6, 9, 9, 9, 9, 10, 10, 15, 17, 20, 23, 23, 27, 28, 31, 32, 32, 34, 35, 36, 36, 36, 36, 38, 39, 41, 42, 42, 43, 45, 47, 49, 49, 50, 50, 51, 51, 54, 55, 55, 57, 57, 57, 57, 57, 59, 59, 61, 61, 63, 67, 72, 74, 76, 76, 80, 80, 81, 81, 81, 82, 83, 85, 87, 88, 90, 93, 95, 96, 97, 97, 99, 100)

12. union:

使用union函数时需要保证两个RDD元素的数据类型相同,返回的RDD数据类型和被合并的RDD元素数据类型相同。并不进行去重操作,保存所有的元素,如果想去重,可以使用distinct()。同时,spark还提供更为简洁的使用union的API,即通过++符号相当于union函数操作。

eg: a 与 b 的联合

scala> val a = sc.parallelize(List(("A",1),("B",2),("c",3),("A",4),("C",5) ))scala> val b = sc.parallelize(List(("A",5),("B",6),("A",4),("C",9) ))scala> a.union(b).collectres22: Array[(String, Int)] = Array((A,1), (B,2), (c,3), (A,4), (C,5), (A,5), (B,6), (A,4), (C,9))

去重复:

scala> val d = sc.parallelize(List(("A",5),("B",6),("A",5) ))scala> d.distinct.collectres25: Array[(String, Int)] = Array((B,6), (A,5))

13. groupBy:

将元素通过函数生成相应的Key,数据就转化为Key-Value格式,之后将Key相同的元素分为一组。

eg:根据数据集中的每个元素的K值对数据分组

scala> val a = sc.parallelize(List(("A",1),("B",2),("c",3),("A",4),("C",5) ))scala> a.groupByKey().collectres21: Array[(String, Iterable[Int])] = Array((B,CompactBuffer(2)), (A,CompactBuffer(1, 4)), (C,CompactBuffer(5)), (c,CompactBuffer(3)))

14. join:

join对两个需要连接的RDD进行cogroup函数操作,将相同key的数据能偶放到一个分区,在cgroup操作之后形成新RDD对每个key下的元素进行笛卡尔积的操作,返回的结果在展平,对应key下的所有元组形成一个集合。最后返回 RDD[(K, (V, W))]。


eg:a与b两个数据连接,相当于表的关联

scala> val a = sc.parallelize(List(("A",1),("B",2),("c",3),("A",4),("C",5) ))scala> val b = sc.parallelize(List(("A",5),("B",6),("A",4),("C",9) ))scala> a.join(b).collectres23: Array[(String, (Int, Int))] = Array((B,(2,6)), (A,(1,5)), (A,(1,4)), (A,(4,5)), (A,(4,4)), (C,(5,9)))

15. cache:

cache将RDD元素从磁盘缓存到内存。相当于 persist(MEMORY_ONLY) 函数的
功能。

16. persist:

persist函数对RDD进行缓存操作,数据缓存在哪里,由StorageLevel这个枚举类型进行确定。DISK 代表磁盘,MEMORY 代表内存, SER 代表数据是否进行序列化存储。

函数定义: persist(newLevel:StorageLevel)

StorageLevel 是枚举类型,代表存储模式。

MEMORY_AND_DISK_SER 代表数据可以存储在内存和磁盘,并且以序列化的方式存储,其他同理。

二:Action:行动算子

1. foreach:

foreach对RDD中的每个元素都应用f函数操作,不返回 RDD 和 Array, 而是返回Uint。

scala> val a = sc.parallelize(List(1,2,3,4,5,6,7,8,9),3)scala> a.foreach(println(_))456789123

2. saveAsTextFile:

函数将数据输出,存储到 HDFS 的指定目录。

函数的内 部实现,其内部通过调用 saveAsHadoopFile 进行实现:

this.map(x => (NullWritable.get(), new Text(x.toString)))

.saveAsHadoopFile[TextOutputFormat[NullWritable, Text]](path)

将 RDD 中的每个元素映射转变为 (null, x.toString),然后再将其写入 HDFS。

3. collect:

collect相当于toArray,不过已经过时不推荐使用,collect将分布式的RDD返回为一个单机的scala Array数据,在这个数组上运用 scala 的函数式操作。

4. count:

count返回整个RDD的元素个数。

scala> val a = sc.parallelize(1 to 10 )scala> a.collectres9: Array[Int] = Array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)                         scala> a.countres10: Long = 10

到此,相信大家对"Spark RDD算子分为哪几类"有了更深的了解,不妨来实际操作一番吧!这里是网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

元素 函数 数据 算子 输入 相同 两个 类型 代表 序列 存储 生成 内存 处理 例子 磁盘 缓存 作业 应用 抽样 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 广东万易互联网科技有限公司惠州分公司 蓝思科技飞鸽互联网 互联网科技公司华为 科技互联网技术 互联网医疗科技 深圳互联网络科技有限公司 西安互联网科技公司 顺网科技2021年互联网排名 科技大学互联网专业好不好 温州喔噻互联网科技有限公司 剑昆互联网络科技有限公司临桂 互联网科技商业 新兴科技互联网创新大赛颁奖典礼 深圳市优智互联网科技有限公司 四川慕妮娅互联网科技有限公司 云南省自由互联网科技有限公司 互联网科技资金流入 江苏互联网智能科技软件 互联网与数字科技关系 郑州欣桑互联网科技有限公司 互联网通讯科技 互联网科技有限公司图片 深圳互联网科技公司 迪茉互联网科技 易通互联网络科技有限公司 新华互联网科技校企合作 成都互联网科技公司工作好不好 互联网金融科技展 互联网数据科技专业 南博望互联网科技有限公司
0