文章目录
1.foreach
遍历rdd中所有的元素。
retRDD.foreach(println)
2.count
统计该rdd中元素的个数,返回值为Long类型。
println(retRDD.count())
3.take
返回该rdd中的前N个元素,如果该rdd的数据是有序的,那么take(n)就是TopN。
println(retRDD.take(2).mkString("[", ", ", "]"))
4.first
take(n)中比较特殊的一个take(1)(0),即take(1)集合中的第一个元素。
println(retRDD.first)
5.collect
字面意思就是收集,拉取的意思,该算子的含义就是将分布在集群中的各个partition中的数据拉回到driver中,进行统一的处理;但是这个算子有很大的风险存在,第一,driver内存压力很大,第二数据在网络中大规模的传输,效率很低;所以一般不建议使用,如果非要用,请先执行filter。
retRDD.filter(_._2 > 2).collect()
retRDD.foreach(println)
6.reduce
reduce是一个action操作,reduceByKey是一个transformation。reduce对一个rdd执行聚合操作,并返回结果,结果是一个值。
val ret = retRDD.reduce {case ((key1, value1), (key2, value2)) => {
(key1 + "|" + key2, value1 + value2)
}}
println(ret)
聚合前后的数据类型是一一致的。
7.countByKey
统计key出现的次数。
val countByKey = retRDD.countByKey()
for ((k, v) <- countByKey) {
println(k + "-->" + v)
}
8.saveAsTextFile
把rdd中的数据保存到文件中,只能指定文件夹,有几个分区就有几个文件,本质上是saveAsHadoopFile[TextOutputFormat[NullWritable, Text]]。
retRDD.saveAsTextFile("file:/F:/test/out/out1")
9.saveAsObjectFile和saveAsSequenceFile
源码:
def saveAsObjectFile(path: String): Unit = withScope {
this.mapPartitions(iter => iter.grouped(10).map(_.toArray))
.map(x => (NullWritable.get(), new BytesWritable(Utils.serialize(x))))
.saveAsSequenceFile(path)
}
saveAsObjectFile本质上是saveAsSequenceFile,就是以二进制的格式将RDD保存在文件中。
使用:
retRDD.saveAsObjectFile("file:/F:/test/out/out2")
10.saveAsHadoopFile和saveAsNewAPIHadoopFile
这二者的主要区别就是OutputFormat的区别:
- saveAshadoopFile使用的是接口org.apache.hadoop.mapred.OutputFormat抽象类中的OutputFormat
- saveAsNewAPIHadoopFile使用的是抽象类org.apache.hadoop.mapreduce.OutputFormat中的OutputFormat
- 一般使用saveAsNewAPIHadoopFile
retRDD.saveAsNewAPIHadoopFile(
"file:/F:/test/out/out3",
classOf[Text],
classOf[IntWritable],
classOf[TextOutputFormat[Text, IntWritable]]
)
完整代码:
package blog.p2
import org.apache.hadoop.io.{IntWritable, Text}
import org.apache.hadoop.mapreduce.lib.output.TextOutputFormat
import org.apache.spark.rdd.RDD
import org.apache.spark.{SparkConf, SparkContext}
/**
* Spark-action操作
*/
object Spark_action {
def main(args: Array[String]): Unit = {
val conf = new SparkConf()
.setAppName(s"${Spark_action.getClass.getSimpleName}")
.setMaster("local[*]")
val sc = new SparkContext(conf)
val retRDD = makeRDD(sc)
//foreach
retRDD.foreach(println)
//count
println(retRDD.count())
//take
println(retRDD.take(2).mkString("[", ", ", "]"))
//first
println(retRDD.first)
//collect
retRDD.filter(_._2 > 2).collect()
retRDD.foreach(println)
//reduce
val ret = retRDD.reduce { case ((key1, value1), (key2, value2)) => {
(key1 + "|" + key2, value1 + value2)
}
}
println(ret)
//countByKey
val countByKey = retRDD.countByKey()
for ((k, v) <- countByKey) {
println(k + "-->" + v)
}
//saveAsTextFile
retRDD.saveAsTextFile("file:/F:/test/out/out1")
//saveAsObjectFile
retRDD.saveAsObjectFile("file:/F:/test/out/out2")
//saveAsNewAPIHadoopFile
retRDD.saveAsNewAPIHadoopFile(
"file:/F:/test/out/out3",
classOf[Text],
classOf[IntWritable],
classOf[TextOutputFormat[Text, IntWritable]]
)
sc.stop()
}
def makeRDD(sc: SparkContext): RDD[(String, Int)] = {
val stuRDD = sc.parallelize(List(
"张三,23,bj",
"李四,24,sh",
"王五,25,sz",
"赵六,26,sh",
"周七,27,bj",
"李八,28,sh"
))
val class2Info: RDD[(String, Int)] = stuRDD.map(line => {
val cls = line.substring(line.lastIndexOf(",") + 1)
(cls, 1)
})
class2Info.aggregateByKey(0)(_ + _, _ + _)
}
}