Spark系列修炼---入门笔记21


核心内容:
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)=
    { //呵呵,这不就是将相同keyvalue放到同一个集合当中嘛:(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,继续努力!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一只懒得睁眼的猫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值