所有RDD行动算子如下:
aggregate、collect、count、first、foreach、reduce、take、takeOrdered、takeSample、saveAsObjectFile、saveAsTextFile
具体解释和例子
1. aggregate
概念
1.将每个分区里面的元素进行聚合,然后用combine函数将每个分区的结果和初始值(zeroValue)进行combine操作。这个函数最终返回的类型不需要和RDD中元素类型一致。
2.在seq中每个值和初始值轮流比较,每个分区返回一个满足条件的值
3.在comb中将初始值和每个分区返回值聚合,得到最终结果
例子解释
1.将初始值和第一个分区中的第一个元素传递给seq函数进行计算,然后将计算结果和第二个元素传递给seq函数,直到计算到最后一个值。第二个分区中也是同理操作。最后将初始值、所有分区的结果经过combine函数进行计算(先将前两个结果进行计算,将返回结果和下一个结果传给combine函数,以此类推)
,并返回最终结果。
2.从上面的代码的输出结果可以看出,1,2,3被分到一个分区中,4,5,6被分到一个分区中。3先和第一个元素1传给seq函数,返回最小值1,然后将1和第二个元素2传给seq函数,返回1,以此类推,最后返回第一个分区中的最小值1。第二个分区一样道理,最后结果返回最小值3.最后将初始值3和两个分区的结果经过combine函数进行计算,先将初始值3和第一个分区的结果1传给combine函数,返回4,然后将4和第二个分区结果3传给combine函数,返回最终结果7。
object Aggregate {
def main(args: Array[String]): Unit = {
val sparkConf = new SparkConf().setAppName("transformations examples").setMaster("local[*]")
val sc = new SparkContext(sparkConf)
val rdd = sc.parallelize(Seq(1, 2, 3, 4, 5, 6), 2)
def seq(a: Int, b: Int): Int = {
println("seq: " + a + "\t " + b)
math.min(a, b)
}
def comb(a: Int, b: Int): Int = {
println("comb: " + a + "\t " + b)
a + b
}
val aggRDD = rdd.aggregate(3)(seq, comb)
println(aggRDD)
sc.stop()
}
}
2. collect
获取整个RDD中的数据,只有当整个数据集能在单台机器的内存中放得下时,才能使用collect(),因此,collect()不能用在大规模数据集上。
object Collect {
def main(args: Array[String]): Unit = {
val sparkConf = new SparkConf().setAppName("transformations examples").setMaster("local[*]")
val sc = new SparkContext(sparkConf)
val rdd = sc.parallelize(List(1, 2, 3))
rdd.collect().foreach(println)
sc.stop()
}
}
3. count
返回数据集元素个数
object Count {
def main(args: Array[String]): Unit = {
val sparkConf = new SparkConf().setAppName("transformations examples").setMaster("local[*]")
val sc = new SparkContext(sparkConf)
val rdd = sc.parallelize(List(1, 2, 3))
val count = rdd.count()
println(count)
sc.stop()
}
}
4. first
返回数据集的第一个元素
object First {
def main(args: Array[String]): Unit = {
val sparkConf = new SparkConf().setAppName("transformations examples").setMaster("local[*]")
val sc = new SparkContext(sparkConf)
val rdd = sc.parallelize(List(1, 2, 3))
println(rdd.first())
sc.stop()
}
}
5. foreach
对RDD中的每个元素使用给定的函数 ,相当于java for循环
object Foreach {
def main(args: Array[String]): Unit = {
val sparkConf = new SparkConf().setAppName("transformations examples").setMaster("local[*]")
val sc = new SparkContext(sparkConf)
val rdd = sc.parallelize(List(1, 2, 3))
rdd.foreach(x => {
val y=x+1
println(y)
})
sc.stop()
}
}
6. reduce
reduce(func):通过函数func先聚集各分区的数据集,再聚集分区之间的数据,func接收两个参数,返回一个新值,新值再做为参数继续传递给函数func,直到最后一个元素
object Reduce {
def main(args: Array[String]): Unit = {
val sparkConf = new SparkConf().setAppName("transformations examples").setMaster("local[*]")
val sc = new SparkContext(sparkConf)
val rdd = sc.parallelize(List(1, 2, 3))
print(rdd.reduce(_+_))
sc.stop()
}
}
7. take
从RDD返回num个元素
object Take {
def main(args: Array[String]): Unit = {
val sparkConf = new SparkConf().setAppName("transformations examples").setMaster("local[*]")
val sc = new SparkContext(sparkConf)
val rdd = sc.parallelize(List("zhangsan", "lisi", "wangwu"))
rdd.take(2).foreach(println)
sc.stop()
}
}
8. takeOrdered
使用它们的自然顺序或自定义比较器返回RDD的前n个元素
object TakeOrdered {
def main(args: Array[String]): Unit = {
val sparkConf = new SparkConf().setAppName("transformations examples").setMaster("local[*]")
val sc = new SparkContext(sparkConf)
val rdd = sc.parallelize(List("zhangsan", "lisi", "wangwu", "zhaoliu"))
// TODO: 添加比较器
rdd.takeOrdered(2).foreach(println)
sc.stop()
}
}
9. takeSample
takeSample(withReplacement, num, [seed]) 返回一个包含数据集的num元素的随机抽样的数组,其中包含或不替换,可选地预先指定一个随机数生成器种子。
object TakeSample {
def main(args: Array[String]): Unit = {
val sparkConf = new SparkConf().setAppName("transformations examples").setMaster("local[*]")
val sc = new SparkContext(sparkConf)
val rdd = sc.parallelize(1 to 10)
val value = rdd.takeSample(false, 5, 5)
value.foreach(x => print(x + " "))
sc.stop()
}
}
10. saveAsObjectFile
将此RDD保存为序列化对象的序列文件。
object SaveAsObjectFile {
def main(args: Array[String]): Unit = {
val sparkConf = new SparkConf().setAppName("transformations examples").setMaster("local[*]")
val sc = new SparkContext(sparkConf)
val rdd = sc.parallelize(List("zhangsan", "lisi", "wangwu"),1)
rdd.saveAsObjectFile("file:///gitRepositories/SparkLearnExample/save_data/")
sc.stop()
}
}
11. saveAsTextFile
将数据集的元素作为文本文件(或一组文本文件)写入本地文件系统、HDFS或任何其他hadoop支持的文件系统的给定目录中。
Spark将在每个元素上调用toString,将其转换为文件中的一行文本。
saveAsTextFile要求保存的目录之前是没有的,否则会报错。所以,最好程序中保存前先判断一下目录是否存在。
一般而言,saveAsTextFile会按照执行task的多少生成多少个文件,比如part-00一直到part-0n,n自然就是task的个数
在路径前面加上hdfs://表示hdfs文件系统,不加默认hdfs
在路径前面加上file://表示本地文件系统
object SaveAsTextFile {
def main(args: Array[String]): Unit = {
val sparkConf = new SparkConf().setAppName("transformations examples").setMaster("local[*]")
val sc = new SparkContext(sparkConf)
val rdd = sc.parallelize(List("zhangsan", "lisi", "wangwu"),1)
rdd.saveAsTextFile("file:///gitRepositories/SparkLearnExample/save_data/")
sc.stop()
}
}