核心内容:
1、Spark中常用的Transformation算子:
map、filter、flatMap、reduceByKey、groupByKey、join(笛卡尔积)、cogroup详解
2、Spark中常用的Action算子:reduce、collect、foreach、savaAsTextFile、sortByKey详解
Spark中常用的Transformation算子用法详解(这些算子都是我们最常用和最核心的算子,都是lazy级别的,Transformation级别的算子每进行一步操作就会产生一个或多个RDD,Action级别的算子不会产生RDD,但是会触发Job):
map:map函数会为每一条输入进行指定的操作,并为每一条输入返回一个对象
flatMap:flatMap则是map和flat两者操作的集合,即首先同map一样,先为每一条输入进行指定的操作,并为每一条输入返回一个对象,随后通过flat将所有对象合并为一个对象;flatMap与map不同的地方在于flatMap传入的函数的返回值必须是一个集合。
filter:filter就是过滤,符合条件的留下,不符合条件的筛选掉,filter会进行布尔值的判断。
reduceByKey : reduceByKey只对key-value pair RDDs可用,将具有相同key的value进行reduce操作,reduceByKey不会触发Job,但是会产生Shuffle。
groupByKey(一个RDD): groupByKey会使用RDD中的键来对数据进行分组,即相同key的value放到同一个集合当中。对于一个由类型K的键和类型V的值组成的RDD,得到的RDD类型会是[K,Iterable[v]]。
join:将两种集合的元素根据他的key聚合到一起,即两个集合基于key进行内容的连接
注意:当出现相同Key时, join会出现笛卡尔积, 而cogroup的处理方式不同
转载网址:http://blog.csdn.net/wo334499/article/details/51689563
cogroup(多个RDD):除了对单个RDD的数据进行分组,还可以使用cogroup()函数对多个共享同一个键的RDD进行分组。对两个键的类型均为K而值得类型分别为V和W的RDD进行cogroup()时,得到结果的RDD类型为[(K,(Iterable[V],Iterable[W]))]。如果其中一个RDD对于另一个RDD中存在的某个键没有对应的记录,那么对应的迭代器则为空。
Spark中常用的Action算子用法详解(Action级别的算子不会产生RDD,但是会触发Job):
sortByKey : 按照key进行排序操作。
呵呵,第一次看到3个阶段的
reduce:reduce将RDD中元素前两个传给输入函数,产生一个新的return值,新产生的return值与RDD中下一个元素(第三个元素)组成两个元素,再被传给输入函数,直到最后只有一个值为止。
直接上总的代码:
package com.appache.spark.app
import org.apache.spark.rdd.RDD
import org.apache.spark.{SparkConf, SparkContext}
/**
* Created by hp on 2016/12/5.
*/
object Transformations
{
def main(args:Array[String]):Unit=
{
//先创建配置信息
val conf = new SparkConf()
conf.setMaster("local") //Spark的本地运行模式
conf.setAppName("Transformations")
val sc:SparkContext = new SparkContext(conf)
mapTransformation(sc)
filterTransformation(sc)
flatMapTransformation(sc)
groupByKeyTransformation(sc)
sortByKeyTransformation(sc)
joinTransformation(sc)
coGroupTransformation(sc)
reduceByKeyTransformation(sc)
sortByKeyAction(sc)
reduceAction(sc)
//呵呵,我怎么感觉groupByKey是分区呢
sc.stop()
}
def mapTransformation(sc:SparkContext)=
{
val list = 1 to 10
val nums:RDD[Int] = sc.parallelize(list) //用scala集合的方式去创建RDD
val mapped:RDD[Int] = nums.map( (item:Int) => item * 2)
mapped.collect().foreach(println) //将结果进行输出
}
def filterTransformation(sc:SparkContext)=
{
val list = 1 to 10
val nums:RDD[Int] = sc.parallelize(list) //用scala集合的方式去创建RDD
val filtered:RDD[Int] = nums.filter(item => item%2 == 0)
filtered.collect().foreach(println)
}
def flatMapTransformation(sc:SparkContext)=
{
val bigData = Array("Scala Spark","Java Hadoop","Java Tachyon")
val bigDataString:RDD[String] = sc.parallelize(bigData)
val words:RDD[String] = bigDataString.flatMap(line=>line.split(" "))
words.collect().foreach(println)
}
def groupByKeyTransformation(sc:SparkContext)=
{ //呵呵,这不就是将相同key的value放到同一个集合当中嘛:(100,CompactBuffer(Spark, Tachyon))
val data:Array[(Int,String)] = Array((100->"Spark"),(100->"Tachyon"),(70->"Hadoop"),(80->"Kafka"))
val dataRDD:RDD[(Int,String)] = sc.parallelize(data)
val grouped:RDD[(Int, scala.Iterable[String])] = dataRDD.groupByKey()
grouped.collect().foreach(ele=>println(ele))
}
def sortByKeyTransformation(sc:SparkContext)=
{
val data = Array("Spark"->10,"Hadoop"->20,"Spark"->20)
val rdd:RDD[(String,Int)]= sc.parallelize(data)
val wordCounts:RDD[(String,Int)] = rdd.reduceByKey(_+_)
wordCounts.collect().foreach(ele => println(ele))
}
def joinTransformation(sc:SparkContext)=
{
val studentNames:Array[(Int,String)] = Array(1->"Spark",2->"Tachyon",3->"Hadoop")
val studentScores:Array[(Int,Int)] = Array(1->100,2->95,3->65)
val names:RDD[(Int,String)] = sc.parallelize(studentNames)
val scores:RDD[(Int,Int)] = sc.parallelize(studentScores)
val studentNameAndScore:RDD[(Int,(String,Int))] = names.join(scores)
studentNameAndScore.collect().foreach(println)
}
def coGroupTransformation(sc:SparkContext)=
{
val arr1:Array[(Int,String)] = Array(1->"Spark",2->"Tachyon",3->"Hadoop",1->"Hbase")
val arr2:Array[(Int,Int)] = Array(1->100,2->90,3->70,1->110,2->95,2->60)
val names:RDD[(Int,String)] = sc.parallelize(arr1)
val scores:RDD[(Int,Int)] = sc.parallelize(arr2)
val nameScores: RDD[(Int, (scala.Iterable[String], scala.Iterable[Int]))] = names.cogroup(scores)
nameScores.foreach(println)
nameScores.foreach(ele=>println("ID:"+ele._1+"\t"+"Name :"+ele._2._1+"\t"+"Score :"+ele._2._2))
}
def reduceByKeyTransformation(sc:SparkContext)=
{
val data = Array("Spark"->1,"Hadoop"->5,"Spark"->5,"Hadoop"->10,"Hbase"->3)
val pair:RDD[(String,Int)] = sc.parallelize(data)
//reduceByKey只对<key,value> pair RDD可用
val wordCounts:RDD[(String,Int)] = pair.reduceByKey((x,y)=>x+y)
wordCounts.collect.foreach(wordnum=>println(wordnum._1+"\t"+wordnum._2))
}
def sortByKeyAction(sc:SparkContext)=
{
val data = Array("Spark"->1,"Hadoop"->5,"Spark"->5,"Hadoop"->10,"Hbase"->3)
val pair:RDD[(String,Int)] = sc.parallelize(data)
//sortByKey先反转在反转
val wordCounts:RDD[(String,Int)] = pair.reduceByKey((x,y)=>x+y)
val wordCounts2:RDD[(Int,String)] = wordCounts.map(wordnum=>(wordnum._2,wordnum._1)).sortByKey(false)
val wordCounts3:RDD[(String,Int)] = wordCounts2.map(wordnum=>(wordnum._2,wordnum._1))
wordCounts3.collect.foreach(wordnum=>println(wordnum._1+"\t"+wordnum._2))
}
def reduceAction(sc:SparkContext)=
{
val data = 1 to 10
val rdd1:RDD[Int] = sc.parallelize(data)
val sum:Int = rdd1.reduce((x:Int,y:Int)=>x+y)
println(sum)
}
}
运行结果:
map函数的运行结果:
2
4
6
8
10
12
14
16
18
20
flatMap函数的运行结果:
Scala
Spark
Java
Hadoop
Java
Tachyon
filter的运行结果:
2
4
6
8
10
reduceByKey的运行结果:
Spark 6
Hbase 3
Hadoop 15
sortByKey的运行结果:
Hadoop 15
Spark 6
Hbase 3
reduce的运行结果:
55
groupByKey的运行结果:
(100,CompactBuffer(Spark, Tachyon))
(80,CompactBuffer(Kafka))
(70,CompactBuffer(Hadoop))
join的运行结果:
(1,(Spark,100))
(3,(Hadoop,65))
(2,(Tachyon,95))
cogroup的运行结果:
(1,(CompactBuffer(Spark, Hbase),CompactBuffer(100, 110)))
(3,(CompactBuffer(Hadoop),CompactBuffer(70)))
(2,(CompactBuffer(Tachyon),CompactBuffer(90, 95, 60)))
实例程序2:groupByKey与cogroup的实例
package com.appache.spark.app
import org.apache.spark.rdd.RDD
import org.apache.spark.{SparkConf, SparkContext}
/**
* Created by hp on 2016/12/5.
*/
object App
{
def main(args: Array[String]): Unit =
{
//先创建配置信息
val conf = new SparkConf()
conf.setMaster("local") //Spark的本地运行模式
conf.setAppName("Transformations")
val sc:SparkContext = new SparkContext(conf)
val data1 = Array(1->"Spark",2->"Hadoop",3->"Scala",1->"Hbase")
val data2 = Array(1->"Spark",2->"Scala",2->"Java")
val rdd1:RDD[(Int,String)] = sc.parallelize(data1)
val rdd2:RDD[(Int,String)] = sc.parallelize(data2)
//在每一个任务task的内部进行合并:即相同key的value放到同一个集合Iterable当中
val rdd11:RDD[(Int,Iterable[String])] = rdd1.groupByKey()
val rdd22:RDD[(Int,Iterable[String])] = rdd2.groupByKey()
rdd11.collect.foreach(println)
rdd22.collect.foreach(println)
/*
*运行结果:
* (1,CompactBuffer(Spark, Hbase))
* (3,CompactBuffer(Scala))
* (2,CompactBuffer(Hadoop))
* ------------------------------
* (1,CompactBuffer(Spark))
* (2,CompactBuffer(Scala, Java))
* */
//然后我们对多个任务的输出进行合并
val rddsum:RDD[(Int,(Iterable[String],Iterable[String]))] = rdd1.cogroup(rdd2)
rddsum.collect.foreach(println)
/*
* 运行结果:
* (1,(CompactBuffer(Spark, Hbase),CompactBuffer(Spark)))
* (3,(CompactBuffer(Scala),CompactBuffer()))
* (2,(CompactBuffer(Hadoop),CompactBuffer(Scala, Java)))
* */
}
}
OK,继续努力!