spark 常用算子 详解

来源:互联网 发布:北京新华电脑学校java 编辑:程序博客网 时间:2024/05/16 00:53

Spark算子可以分成两大类:
1.Transformation类算子
2.Action类算子。
转换(转化操作)算子,这类转化操作为懒执行,不会触发提交作业,从而也不会处理中间过程。Transformation 操作是延迟计算的,也就是说从一个RDD 转换生成另一个 RDD 的转换操作不是马上执行,需要等到有 Action 操作的时候才会真正触发运算。
行动算子,这类算子会触发SparkContext提交Job作业。
一、Transformation 转换算子:
RDD中的所有转换都是延迟加载的,也就是说,它们并不会直接计算结果。相反的,它们只是记住这些应用到基础数据集(例如一个文件)上的转换动作。只有当发生一个要求返回结果给Driver的动作时,这些转换才会真正运行。这种设计让Spark更加有效率地运行。

  1. Map算子:map(func)

map是对RDD中的每个元素都执行一个指定的函数(func 传进来的逻辑)处理之后来产生一个新的RDD(注意:不是每个元素产生一个新的RDD,而是一起产生一个新的RDD)。任何原RDD中的元素在新RDD中都有且只有一个元素与之对应,即一一对应。Map传给func 的参数是每个元素。

这里写图片描述

Scala:
这里写图片描述

Java:
这里写图片描述

2. flatMap算子:flatMap(func)
类似于map,但是每一个输入元素,会被映射为0到多个输出元素(因此,func函数的返回值是一个Seq,而不是单一元素),最后映射结果整合。

这里写图片描述

Scala:
这里写图片描述
这里写图片描述

Java:
这里写图片描述

测试样例:

scala> val rdd1 = sc.parallelize(1 to 4, 2)scala> val rdd2= rdd1.flatMap(x => 1 to x)//每个元素扩展scala> rdd2.collectres1: Array[Int] = Array(1, 1, 2, 1, 2, 3, 1, 2, 3, 4)

3.mapPartitions算子
map是对每个元素操作, mapPartitions是对其中的每个partition操作,即map传给处理函数的是每个元素,而mapPartition传给处理函数的是一个分区的元素的迭代器(Iterator)
mapPartitions是map的一个变种。map的输入函数是应用于RDD中每个元素,而mapPartitions的输入函数是应用于每个分区,也就是把每个分区中的内容作为整体来处理的。
源码定义为:

def mapPartitions[U: ClassTag](f: Iterator[T] => Iterator[U], preservesPartitioning: Boolean = false): RDD[U]

f为输入函数,它处理每个分区里面的内容。每个分区中的内容将以Iterator[T]传递给输入函数f,f的输出结果是Iterator[U]。最终的RDD由所有分区经过输入函数处理后的结果合并起来的。
mapPartition 与map:
该函数和map函数类似,只不过映射函数的参数由RDD中的每一个元素变成了RDD中每一个分区的迭代器。如果在映射的过程中需要频繁创建额外的对象,使用mapPartitions要比map高效的过。

比如,将RDD中的所有数据通过JDBC连接写入数据库,如果使用map函数,可能要为每一个元素都创建一个connection,这样开销很大,如果使用mapPartitions,那么只需要针对每一个分区建立一个connection。

*********未完待续********