Spark常用算子总结
// Transformation算子
1、map算子
接收一个函数,对于RDD中的每一个元素执行此函数操作,结果作为返回值。
val rdd = sc.parallelize(Array(1, 2, 3, 4), 1)
rdd.map(x => x*x).foreach(println) // 1 4 9 16
2、filter
接收一个函数,对于RDD中的每一个元素执行此函数操作,留下结果为true的项。
val rdd = sc.parallelize(Array(1, 2, 3, 4), 1)
rdd.filter(_>2).foreach(println) // 3 4
3、flatMap
和map差不多,只是对于每个输入项返回结果有多个,类似一对多映射。用wordCount的例子看:
sc.textFile(“test.txt”)
.flatMap(_.split(” “)) // 一对多映射,每行处理后返回多个单词
.map((_, 1)) // 每个单词映射成pairRDD
.reduceByKey(+)
.collect()
.foreach(println)
// 下面是4个集合操作
4、union
合并两个RDD
5、intersection
求两个RDD的交集
6、subtract
求两个RDD的差集
7、cartesian
求两个RDD的笛卡儿积
// Action算子
8、reduce
接收两个同类型的元素,返回一个同样类型的元素
val rdd = sc.parallelize(Array(1, 2, 3, 4), 1)
rdd.reduce(+) // 求和
9、fold
和reduce类似,有初始值
rdd.fold(0)((x, y) => x+y) // 求和
10、aggregate
和fold一样也有初始值,但类型可以和RDD的类型不同,利用aggregate来去重
val rdd = sc.parallelize(Array(1, 2, 2, 3, 4, 4, 4, 5), 1)
rdd.aggregate(collection.mutable.SetInt)((set, x) => set+=x, (set1, set2) => set1++set2)
.foreach(println)
这里初始值是一个空集合Set,首先在本地进行聚合,也就是将元素放进Set去重。
之后在不同的结点上的进行聚合,也就是Set和Set进行合并。
先在本地聚合有助于减少shuffle的量,减少下一个stage进行计算量。
reduceByKey,combineByKey,aggregateByKey都有这种效果。
// 持久化
11、cache和persist
Spark2.2.0手册中是这样写的
In addition, each persisted RDD can be stored using a different storage level, allowing you,
for example, to persist the dataset on disk, persist it in memory but as serialized Java objects (to save space),
replicate it across nodes. These levels are set by passing a StorageLevel object (Scala, Java, Python) to persist().
The cache() method is a shorthand for using the default storage level, which is StorageLevel.MEMORY_ONLY (store deserialized objects in memory)
也就是说cache()是persist()的特例,默认是Memory_only。
persist的声明如下:
def persist(newLevel : org.apache.spark.storage.StorageLevel) : RDD.this.type = {}
官方也列出了几种StorageLevel:
MEMORY_ONLY RDD会被反序列化成JAVA对象存于JVM中,超出部分如果之后计算中用到就重新计算
MEMORY_AND_DISK 与上面类似,但是超出部分会持久化到磁盘上,之后计算如果用到就从磁盘上读取
MEMORY_AND_SER RDD以字节数组的型式存于JVM中,超出部分如果之后计算中用到就重新计算,字节数组比JAVA对象空间效率更高。
MEMORY_AND_DIST_SER 和上面类似,但是超出部分会持久化到磁盘上,之后计算如果用到就从磁盘上读取
DISK_ONLY 存于磁盘上
MEMORY_ONLY_2 和上面一样,只是数据的副本为2
MEMORY_AND_DISK_2
12、repartition和coalesce
repartition是coalesce中shuffle参数为true时的实现
需要稍微减少分区可以用coalesce这样就可以减少shuffle
如果要增加分区或者分区减少到1或特别少的时候,可以使用repartition或coalesce(1, true)