zoukankan      html  css  js  c++  java
  • Spark(二)算子详解

    Spark(二)算子讲解

    @

    一、wordcountcount

    基于上次的wordcount,我们来写一个wordcountcount,来对wc程序进行第二次计数,我们来分析一下性能。

    package com.littlepage.wc
    
    import org.apache.spark.rdd.RDD
    import org.apache.spark.{SparkConf, SparkContext}
    
    object WordCount {
      def main(args: Array[String]): Unit = {
        val conf=new SparkConf().setAppName("wc").setMaster("local")
        val sparkContext=new SparkContext(conf)
        sparkContext.setLogLevel("error")
        val fileRDD:RDD[String] = sparkContext.textFile("data/data")
        val words:RDD[String] = fileRDD.flatMap(_.split(" "))
        val pairWord:RDD[(String,Int)] = words.map((_,1))
        val res:RDD[(String,Int)] = pairWord.reduceByKey(_+_)
        println("wordcount:")
        res.foreach(println)
        val rev:RDD[(Int,Int)] = res.map((x)=>{(x._2,1)})
        val pl:RDD[(Int,Int)] = rev.reduceByKey(_+_)
        println("
    wordcountcount")
        pl.foreach(println)
        Thread.sleep(100000000)
      }
    }
    

    通过性能图,我们可以知道:

    1.Spark如果不对其结果进行存储或输出,那么Spark将不会处理map或者reduce操作

    2.如果进行重复输出,共用的map或者reduce操作只执行一次

    3.默认如果产生一次shuffle是去查看图表的一次拐弯,为了尽量减少性能的消耗,编写程序时应该尽量减少shuffle的次数

    二、编程模型

    Spark编程模型和MapReduce相比,Spark可以多个Job,多个State进行执行。

    源码部分参考视频

    三、RDD数据集和算子的使用

    1.三个必备算子

    我们在写一个Spark程序中,不可避免的算子有三个,创建算子,转换算子,收集算子。

    创建算子可以创建一个RDD数据集,这个创建可以在内存中(集合容器),也可以在硬盘中(文件)获取

    转换算子可以处理一个RDD数据集,即map和reduce操作,都算做转换算子。

    收集算子我们在写一个RDD数据集的时候,必须使用收集算子进行收集,否则不会触发shuffle。

    示例,三个算子写一个过滤数字程序。

    package com.littlepage
    
    import org.apache.spark.rdd.RDD
    import org.apache.spark.{SparkConf, SparkContext}
    
    object demo2 {
      def main(args: Array[String]): Unit = {
        val conf=new SparkConf().setAppName("demo2").setMaster("local")
        val sc=new SparkContext(conf)
        sc.setLogLevel("error")
        val dataRDD: RDD[Int] = sc.parallelize(List(1,2,3,4,5,6,7,6,5,4,3,2,1))//创建算子
        val filterRDD: RDD[Int] = dataRDD.filter(_>3)//转换算子
        val ints:Array[Int] = filterRDD.collect()//收集算子
        Thread.sleep(100000)
      }
    }
    
    package com.littlepage
    
    import org.apache.spark.rdd.RDD
    import org.apache.spark.{SparkConf, SparkContext}
    
    object demo2 {
      def main(args: Array[String]): Unit = {
        val conf=new SparkConf().setAppName("demo2").setMaster("local")
        val sc=new SparkContext(conf)
        sc.setLogLevel("error")
        val dataRDD: RDD[Int] = sc.parallelize(List(1,2,3,4,5,6,7,6,5,4,3,2,1))//创建算子
        val filterRDD: RDD[Int] = dataRDD.filter(_>3)//转换算子
        val ints:Array[Int] = filterRDD.collect()//收集算子
        Thread.sleep(100000)
      }
    }
    
    2.常见算子(交并差笛卡尔,cogroup,join)

    2.1.union算子

    将两个数据集合并为一个数据集,直接合并,不会产生shuffle

    object union {
      def main(args: Array[String]): Unit = {
        val sc=new SparkContext(new SparkConf().setMaster("local").setAppName("union"))
        sc.setLogLevel("error")
        val rdd1:RDD[Int] = sc.parallelize(List(1,2,3,4,6,7))
        val rdd2:RDD[Int] = sc.parallelize(List(2,3,4,5))
        val uniondata = rdd1.union(rdd2)
        uniondata.foreach(print)
        Thread.sleep(100000)
      }
    }
    

    2.2.intersection算子

    将2个数据集取交集,产生一个shuffle

    val interdata:RDD[Int] = rdd1.intersection(rdd2)
    

    2.3.substract算子

    将2个数据集取差集,产生一个shuffle

    val subdata:RDD[Int] = rdd1.substract(rdd2)
    

    2.4.cartesian算子

    将2个数据集取笛卡尔积,不产生shuffle

    val cartesiandata:RDD[Int] = rdd1.cartesian(rdd2)
    

    2.5.cogroup算子

    两个分组进行,key作为结果的key,value集合进行一个二元祖,包含两个分区的元素,产生一个shuffle。

    val rdd1:RDD[(String,Int)] = sc.parallelize(List(
          ("zhangsan",11),
          ("zhangsan",12),
          ("lisi",13),
          ("wangwu",14)
        ));
        val rdd2:RDD[(String,Int)] = sc.parallelize(List(
          ("zhangsan",21),
          ("zhangsan",22),
          ("lisi",23),
          ("zhaoliu",28)
        ))
        val cogroupdata:RDD[(String,(Iterable[Int],Iterable[Int]))] = rdd1.cogroup(rdd2)
    

    6.join,leftOuterJoin,rightOuterJoin,fullOuterJoin算子

    val joindata:RDD[(String,(Int,Int))] = rdd1.join(rdd2)
    val leftdata:RDD[(String,(Int,Option[Int]))] = rdd1.leftOuterJoin(rdd2)
    val rightdata:RDD[(String,(Option[Int],Int))]  = rdd2.rightOuterJoin(rdd2)
    val fulldata:RDD[(String,(Option[Int],Option[Int]))]  = rdd1.fullOuterJoin(rdd2)
    
    3.排序和聚合计算

    3.1.swap算子

    将一个k-v数据集的key和value交换,用法

    data.map(_.swap)
    

    3.2.sort算子

    sort算子可以将按照key进行全排序

    data.sortByKey()
    

    3.3.take算子

    获得数据的前n个,n为一个整型

    data.take(n)
    

    3.4.distinct去重

    去除key相同的

    val keys:RDD[(String,String) = map.distinct()
    
  • 相关阅读:
    2月4日学习日志
    2月3日学习日志
    2月2日学习日志
    2月1日学习日志
    Result Maps collection already contains value for ***
    mapreduce入门程序之---wordcount
    利用Git上传项目到github以及遇到的问题
    看100篇架构设计的文章,不如重构一次代码
    面试中的微服务架构
    分布式架构中数据一致性常见的几个问题
  • 原文地址:https://www.cnblogs.com/littlepage/p/11751867.html
Copyright © 2011-2022 走看看