操作系统:CentOS-7.8
Spark版本:2.4.4
scala版本:2.11.12
本篇文章锤子和大家一起学习Spark RDD的常用Action算子,锤子会对每个算子含义和入参进行说明,并附上演示代码,帮助大家快速理解和使用这些常用算子(由于Spark的RDD算子还是比较多的,本篇文章主要列出的是一些常用的,后续如果学习更多了再继续补充),完整示例代码的GitHub地址:https://github.com/telundusiji/dream-hammer/tree/master/module-8
关于Spark学习的其他知识可以参考
reduce
说明
对整个结果集进行归约,最终生成一条数据,是整个数据集的汇总
方法
def reduce(f: (T, T) => T): T
参数
- f -> 归约的处理函数,函数两个入参,第一个是归约的局部结果,第二个是当前的一条数据
其他
- 注意区分reduce和reduceByKey,reduce是一个action操作,不属于shuffle,reduceByKey是transformation操作中的shuffle操作
- reduce是在每个分区上先进行归约,然后再将各个分区的归约结果汇总成一条数据
示例
def reduceTest(): Unit = {
val sourceRdd = sc.parallelize(Seq(1, 1, 1, 1, 1))
sourceRdd.collect()
val result = sourceRdd
.reduce((agg, curr) => agg * 2 + curr)
println(result)
sc.stop()
}
//运行结果
/*
31
*/
collect
说明
以数组的形式获取结果集RDD中的所有数据
方法
def collect(): Array[T]
其他
- 由于collect会从远程集群拉取数据到driver端,所以当数据量大时使用collect会将大量数据汇集到一个driver节点上,容易造成内存溢出
示例
def collectTest(): Unit = {
val sourceRdd = sc.parallelize(Seq(1, 2, 3))
sourceRdd.collect()
val result: Array[Int] = sourceRdd.collect()
result.foreach(println(_))
sc.stop()
}
//运行结果
/*
1
2
3
*/
foreach
说明
遍历结果集RDD中每一个元素
方法
def foreach(f: T => Unit): Unit
示例
def foreachTest(): Unit = {
val sourceRdd = sc.parallelize(Seq(1, 2, 3))
sourceRdd.collect()
sourceRdd.foreach(println(_))
sc.stop()
}
//运行结果
/*
1
2
3
*/
count
说明
求结果集的数量
示例
def countTest(): Unit = {
val sourceRdd = sc.parallelize(Seq(1, 2, 3))
val result = sourceRdd.count()
println(result)
sc.stop()
}
//运行结果
/*
3
*/
countByKey
说明
按照key进行分组后,计算每个分组中的元素数量
示例
def countByKeyTest(): Unit = {
val sourceRdd = sc.parallelize(Seq(("a", "value"), ("b", "value"), ("b", "value"), ("c", "value"), ("a", "value")))
val result: collection.Map[String, Long] = sourceRdd.countByKey()
result.foreach(println(_))
sc.stop()
}
//运行结果
/*
(a,2)
(b,2)
(c,1)
*/
first
说明
获取RDD中的第一个元素
示例
def firstTest(): Unit = {
val sourceRdd = sc.parallelize(Seq(1, 2, 3))
val result = sourceRdd.first()
println(result)
sc.stop()
}
//运行结果
/*
1
*/
take
说明
获取RDD中的前n个元素
其他
- 当你只需要获取第一个元素时,建议使用first,因为take中会从多个分区中收集数据,相对first来说效率比较低
示例
def takeTest(): Unit = {
val sourceRdd = sc.parallelize(Seq(1, 3, 2, 1, 5))
val result = sourceRdd.take(3)
result.foreach(println(_))
sc.stop()
}
//运行结果
/*
1
3
2
*/
takeSample
说明
采样一个RDD中的数据,与转换算子中的sample操作类似,不同的是sample操作是action操作
方法
def takeSample(
withReplacement: Boolean,
num: Int,
seed: Long = Utils.random.nextLong): Array[T]
参数
- withReplacement:采样数据是否有放回,true代表又放回采样,false代表无放回采样
- num:采样个数
- seed:随机种子
示例
def takeSampleTest(): Unit = {
val sourceRdd = sc.parallelize(Seq(1, 3, 2, 1, 5))
val result = sourceRdd.takeSample(false, 3, 100)
result.foreach(println(_))
sc.stop()
}
//运行结果
/*
2
3
1
*/