Spark算子:RDD常用的10种执行算子 & 3种常见保存路径

目录

1. reduce(func)

2. collect()

3. count()

4. first()

5. take(n)

6. takeOrdered(n)

7. aggregate()

8. fold(num)(func)

9. 三种常用RDD元素保存路径

10. countByKey

11. foreach(func)、foreachPartition(func)


首先说一下transformation算子和action算子的区别:

Transformation操作会由一个RDD生成一个新的 RDD。Transformation操作是延迟计算的,也就是说从一个RDD转换生成另一个RDD的转换操作不是马上执行,需要等到Actions操作时,才真正开始运算。

Action操作会对 RDD 计算出一个结果,并把结果返回到驱动器程序Driver中,或把结果存储到外部存储系统(如 HDFS)中。

下面总结了一下常用的10种RDD的常用action算子的用法:

1. reduce(func)

通过func函数来对RDD中所有元素进行聚合运算,先运算分区内数据,再运算分区间数据

eg:对Int类型RDD

scala> val rdd1 = sc.makeRDD(1 to 10,2)
rdd1: org.apache.spark.rdd.RDD[Int] = ParallelCollectionRDD[0] at makeRDD at <console>:24

scala> rdd1.reduce(_+_)
res0: Int = 55 

eg:对String类型RDD

scala> val rdd2 = sc.makeRDD(Array(("a",1),("b",2),("c",3),("d",4)))
rdd2: org.apache.spark.rdd.RDD[(String, Int)] = ParallelCollectionRDD[0] at makeRDD at <console>:24

scala> rdd2.reduce((x,y)=>(x._1+y._1,x._2+y._2))
res0: (String, Int) = (bdac,10)  

2. collect()

在驱动程序Driver中或存储到HDFS等存储工具中,以数组的形式返回数据集的所有元素

scala> val rdd2 = sc.makeRDD(1 to 10)
rdd2: org.apache.spark.rdd.RDD[Int] = ParallelCollectionRDD[1] at makeRDD at <console>:24

scala> rdd2.collect
res1: Array[Int] = Array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)

3. count()

返回RDD中元素的个数

scala> val rdd3 = sc.makeRDD(1 to 8)
rdd3: org.apache.spark.rdd.RDD[Int] = ParallelCollectionRDD[2] at makeRDD at <console>:24

scala> rdd3.count
res2: Long = 8

4. first()

返回RDD中第一个元素

scala> val rdd4 = sc.makeRDD(1 to 9)
rdd4: org.apache.spark.rdd.RDD[Int] = ParallelCollectionRDD[3] at makeRDD at <console>:24

scala> rdd4.first
res3: Int = 1

5. take(n)

返回一个由RDD前n个元素组成的数组

scala> val rdd5 = sc.makeRDD(Array(2,4,5,6,8,9,7))
rdd5: org.apache.spark.rdd.RDD[Int] = ParallelCollectionRDD[4] at makeRDD at <console>:24

scala> rdd5.take(4)
res4: Array[Int] = Array(2, 4, 5, 6)

6. takeOrdered(n)

返回原RDD排序(默认升序排)后,前n个元素组成的数组

scala> val rdd6 = sc.makeRDD(Array(2,5,6,4,3,8,9))
rdd6: org.apache.spark.rdd.RDD[Int] = ParallelCollectionRDD[5] at makeRDD at <console>:24

scala> rdd6.takeOrdered(4)
res5: Array[Int] = Array(2, 3, 4, 5)

7. aggregate()

与key-value类型RDD的转换算子aggregateByKey类似,同样是三个参数:

初始值zeroValue,分区内函数seqOp,分区间函数combOp

eg:创建RDD,将所有元素相加

scala> val rdd7 = sc.makeRDD(1 to 10 , 2)
rdd7: org.apache.spark.rdd.RDD[Int] = ParallelCollectionRDD[7] at makeRDD at <console>:24

scala> rdd7.aggregate(0)(_+_,_+_)
res6: Int = 55

scala> rdd7.aggregate(1)(_*_,_*_)
res7: Int = 3628800

8. fold(num)(func)

与key-value类型RDD的foldByKey类似,分区内核分区间函数一致,属于aggregate(zerovalue)(seqOp,combOp)的简化操作

scala> rdd7.fold(0)(_+_)
res8: Int = 55

9. 三种常用RDD元素保存路径

(1)savaAsTextFile(path)

将数据集元素以textfile形式保存到HDFS中或其他文件系统中,对于每个元素,Spark会调用toString方法

(2)savaAsSequenceFile(path)

将数据集元素以Hadoop SequenceFile格式保存到本地指定目录下

(3)savaAsObjectFile(path)

将数据集元素序列化成对象保存到HDFS系统中的文件中

10. countByKey

前面count执行算子是计算RDD中元素个数,countByKey是针对(K,V)类型的RDD,返回一个(K,Int)类型的map,表示每一个key对应的元素个数

与GroupByKey、ReduceByKey类似,都是对相同key的value进行聚合运算,count指统计总数

scala> val rdd10 = sc.parallelize(List((1,3),(1,2),(1,4),(2,3),(3,6),(3,8)),3)
rdd10: org.apache.spark.rdd.RDD[(Int, Int)] = ParallelCollectionRDD[8] at parallelize at <console>:24

scala> rdd10.countByKey
res15: scala.collection.Map[Int,Long] = Map(3 -> 2, 1 -> 3, 2 -> 1)

11. foreach(func)、foreachPartition(func)

遍历原RDD元素经过func函数运算过后的结果集

scala> var acc = sc.accumulator(1)
warning: there were two deprecation warnings; re-run with -deprecation for details
acc: org.apache.spark.Accumulator[Int] = 1

scala> var rdd11 = sc.makeRDD(1 to 10,2)
rdd11: org.apache.spark.rdd.RDD[Int] = ParallelCollectionRDD[13] at makeRDD at <console>:24

scala> rdd11.foreach(x => acc+=x)

scala> acc.value
res27: Int = 56

scala> rdd11.foreach(println)
6
1
2
3
7
8
9
10
4
5

scala> rdd11.collect.foreach(println)
1
2
3
4
5
6
7
8
9
10

直接foreach println时是无序打印,用collect算子后才是有序打印;

数据多的时候可以分区处理,foreachPartition算子分区操作。

猜你喜欢

转载自blog.csdn.net/wx1528159409/article/details/87603286
今日推荐