spark-day03-核心编程-RDD算子

一:RDD算子

RDD算子也称为RDD方法,主要分为两类。转换算子和行动算子。

spark-day03-核心编程-RDD算子_第1张图片

二:RDD转换算子

        根据数据处理方式的不同将算子整体上分为value类型、双value类型和key-value类型

        2.1:map值转换

package com.atguigu.bigdata.spark.rdd.operator.transform

import org.apache.spark.{SparkConf, SparkContext}
import org.apache.spark.rdd.RDD

object Spark01_RDD_Operator_Transform {
  def main(args: Array[String]): Unit = {
    //准备环境
    val sparkConf = new SparkConf().setMaster("local[*]").setAppName("RDD")
    val sc = new SparkContext(sparkConf)
    //创建RDD
    val rdd = sc.makeRDD(List(1,2,3,4))
    def mapFunction(num:Int):Int = {
      num * 2
    }
    val mapRDD:RDD[Int] = rdd.map(mapFunction)
    mapRDD.collect().foreach(println)     //2 4 6 8
    //关闭环境
    sc.stop()
  }
}

        2.2:map并行效果展示

package com.atguigu.bigdata.spark.rdd.operator.transform

import org.apache.spark.{SparkConf, SparkContext}

object Spark01_RDD_Operator_Transform_Par {
  def main(args: Array[String]): Unit = {
    //准备环境
    val sparkConf = new SparkConf().setMaster("local[*]").setAppName("RDD")
    val sc = new SparkContext(sparkConf)
    //创建RDD
    //1.rdd的计算,一个分区内的数据一个一个执行逻辑
    //  只有前面一个数据全部的逻辑执行完毕后,才会执行下一个数据
    //  分区内数据的执行是有序的
    //2.不同分区数据计算是无序的
    val rdd = sc.makeRDD(List(1,2,3,4))
    val mapRDD = rdd.map(
      num => {
        println(">>>>>>" + num)
        num
      }
    )
    val mapRDD1 = mapRDD.map(
      num => {
        println("#####" + num)
        num
      }
    )
    mapRDD1.collect()
    //关闭环境
    sc.stop()
  }
}

        2.3:mapPartitions:可以以分区为单位进行数据转换操作

package com.atguigu.bigdata.spark.rdd.operator.transform

import org.apache.spark.{SparkConf, SparkContext}
import org.apache.spark.rdd.RDD

object Spark02_RDD_Operator_Transform {
  def main(args: Array[String]): Unit = {
    //准备环境
    val sparkConf = new SparkConf().setMaster("local[*]").setAppName("RDD")
    val sc = new SparkContext(sparkConf)
    //创建RDD
    val rdd = sc.makeRDD(List(1,2,3,4),2)
    val mapRDD:RDD[Int] = rdd.mapPartitions(
      //执行的次数就是分区的个数
      iter => {
        println(">>>>>>>>")
        iter.map(_*2)
      }
    )
    mapRDD.collect().foreach(println)     //2 4 6 8
    //关闭环境
    sc.stop()
  }
}

        2.4:map和mapPartitions的区别

数据处理角度

        map:分区内一个数据一个数据的执行,类似于串行操作。

        mapParitions:以分区为单位进行批处理操作。

功能的角度

        map:将数据源中的数据进行转换和改变,但是不会减少或增多数据

        mapParitions:需要传递一个迭代器,返回一个迭代器,没有要求的元素的个数保持不变,所以可以增加或者减少数据。

性能的角度

        map:类似于串行操作,性能比较低。

        mapParitions:类似于批处理操作,性能较高。但是会长时间占用内容,这样会导致内存不够用,出现内存溢出的错误。所以在内存有限的情况下,不推荐使用。使用map操作。

         2.5:mapParitionsWithIndex:获取指定分区

package com.atguigu.bigdata.spark.rdd.operator.transform

import org.apache.spark.{SparkConf, SparkContext}
import org.apache.spark.rdd.RDD

object Spark03_RDD_Operator_Transform {
  def main(args: Array[String]): Unit = {
    //准备环境
    val sparkConf = new SparkConf().setMaster("local[*]").setAppName("RDD")
    val sc = new SparkContext(sparkConf)
    //创建RDD
    //获取第二个分区内的数据
    val rdd = sc.makeRDD(List(1,2,3,4),2)
    val mapRDD:RDD[Int] = rdd.mapPartitionsWithIndex(
      (index,iter) => {
        if (index == 1){
          iter
        }else{
          Nil.iterator
        }
      }
    )
    mapRDD.collect().foreach(println)     //2 4 6 8
    //关闭环境
    sc.stop()
  }
}

        2.6:flatmap:扁平化操作

package com.atguigu.bigdata.spark.rdd.operator.transform

import org.apache.spark.{SparkConf, SparkContext}
import org.apache.spark.rdd.RDD

object Spark04_RDD_Operator_Transform {
  def main(args: Array[String]): Unit = {
    //准备环境
    val sparkConf = new SparkConf().setMaster("local[*]").setAppName("RDD")
    val sc = new SparkContext(sparkConf)
    //创建RDD
    val rdd:RDD[List[Int]] = sc.makeRDD(List(List(1,2),List(3,4)))
    val flatRDD:RDD[Int] = rdd.flatMap(
      list => {
        list
      }
    )
    flatRDD.collect().foreach(println)
    //关闭环境
    sc.stop()
  }
}

        2.6:扁平化练习:输出1,2,3,4,5

package com.atguigu.bigdata.spark.rdd.operator.transform

import org.apache.spark.{SparkConf, SparkContext}

object Spark04_RDD_Operator_Transform {
  def main(args: Array[String]): Unit = {
    //准备环境
    val sparkConf = new SparkConf().setMaster("local[*]").setAppName("RDD")
    val sc = new SparkContext(sparkConf)
    //创建RDD
    val rdd = sc.makeRDD(List(List(1,2),3,List(4,5)))
    val flatRDD = rdd.flatMap(
      date => {
        date match {
          case list:List[_] => list
          case dat => List(dat)
        }
      }
    )
    flatRDD.collect().foreach(println)
    //关闭环境
    sc.stop()
  }
}

        2.7:glom

package com.atguigu.bigdata.spark.rdd.operator.transform

import org.apache.spark.rdd.RDD
import org.apache.spark.{SparkConf, SparkContext}

object Spark05_RDD_Operator_Transform {
  def main(args: Array[String]): Unit = {
    //准备环境
    val sparkConf = new SparkConf().setMaster("local[*]").setAppName("RDD")
    val sc = new SparkContext(sparkConf)
    //创建RDD
    val rdd:RDD[Int] = sc.makeRDD(List(1,2,3,4),2)

    //List => Int
    //Int => List
    val glomRDD:RDD[Array[Int]] = rdd.glom()

    glomRDD.collect().foreach(data=>println(data.mkString(",")))
    //关闭环境
    sc.stop()
  }
}

        2.8:glom案例:计算所有分区最大值求和,分区内最大值,分区间最大值求和

package com.atguigu.bigdata.spark.rdd.operator.transform

import org.apache.spark.{SparkConf, SparkContext}
import org.apache.spark.rdd.RDD

object Spark06_RDD_Operator_Transform_Test {
  def main(args: Array[String]): Unit = {
    //准备环境
    val sparkConf = new SparkConf().setMaster("local[*]").setAppName("RDD")
    val sc = new SparkContext(sparkConf)
    //创建RDD
    val rdd:RDD[Int] = sc.makeRDD(List(1,2,3,4),2)

    val glomRDD:RDD[Array[Int]] = rdd.glom()

    val maxRDD:RDD[Int] = glomRDD.map(
      array => {
        array.max
      }
    )
    println(maxRDD.collect().sum)
    //关闭环境
    sc.stop()
  }
}

        2.9分区不变的含义,分区名字以及数据都是不变的,output有00000和00001分别是1,2和3,4。output1有00000和00001,分别是2,4和6,8.

package com.atguigu.bigdata.spark.rdd.operator.transform

import org.apache.spark.{SparkConf, SparkContext}

object Spark01_RDD_Operator_Transform_Part {
  def main(args: Array[String]): Unit = {
    //准备环境
    val sparkConf = new SparkConf().setMaster("local[*]").setAppName("RDD")
    val sc = new SparkContext(sparkConf)
    //创建RDD
    val rdd = sc.makeRDD(List(1,2,3,4),2)
    rdd.saveAsTextFile("output")
    //
    val mapRDD = rdd.map(_*2)

    mapRDD.saveAsTextFile("output1")
    //关闭环境
    sc.stop()
  }
}

        2.10:groupby,分组和分区并没有必然的关系。groupby会将数据 打乱,重新组合(shuffle)

package com.atguigu.bigdata.spark.rdd.operator.transform

import org.apache.spark.{SparkConf, SparkContext}
import org.apache.spark.rdd.RDD

object Spark06_RDD_Operator_Transform {
  def main(args: Array[String]): Unit = {
    //准备环境
    val sparkConf = new SparkConf().setMaster("local[*]").setAppName("RDD")
    val sc = new SparkContext(sparkConf)
    //创建RDD
    val rdd:RDD[Int] = sc.makeRDD(List(1,2,3,4),2)

    //groupby会将数据源中的每一个数据进行分组判断,根据返回的分组key进行分组
    //相同的key值的数据会放置在一个组中
    def groupFunction(num:Int):Int = {
      num % 2
    }

    val groupRDD:RDD[(Int,Iterable[Int])] = rdd.groupBy(groupFunction)
    groupRDD.collect().foreach(println)
    //关闭环境
    sc.stop()
  }
}
package com.atguigu.bigdata.spark.rdd.operator.transform

import org.apache.spark.{SparkConf, SparkContext}
import org.apache.spark.rdd.RDD

object Spark06_RDD_Operator_Transform1 {
  def main(args: Array[String]): Unit = {
    //准备环境
    val sparkConf = new SparkConf().setMaster("local[*]").setAppName("RDD")
    val sc = new SparkContext(sparkConf)
    //创建RDD
    //按照首字母来进行分组,分组和分组并没有必然的关系
    val rdd = sc.makeRDD(List("hello","spark","scala","hadoop"),2)

    val groupRDD = rdd.groupBy(_.charAt(0))
    groupRDD.collect().foreach(println)
    //关闭环境
    sc.stop()
  }
}

        2.11:filter。数据过滤操作。可能会造成数据倾斜。比如之前两个分区,分别有1000条数据,过滤之后,可能造成两个分区内的数据量差别比较大。

package com.atguigu.bigdata.spark.rdd.operator.transform

import org.apache.spark.{SparkConf, SparkContext}
import org.apache.spark.rdd.RDD

object Spark07_RDD_Operator_Transform {
  def main(args: Array[String]): Unit = {
    //准备环境
    val sparkConf = new SparkConf().setMaster("local[*]").setAppName("RDD")
    val sc = new SparkContext(sparkConf)
    //创建RDD
    val rdd:RDD[Int] = sc.makeRDD(List(1,2,3,4))
    val filter:RDD[Int] = rdd.filter(num=>num%2!=0)

    filter.collect().foreach(println)
    //关闭环境
    sc.stop()
  }
}

        2.12:sample:数据抽取操作,可以根据随机抽取来判断是什么影响数据倾斜问题。

package com.atguigu.bigdata.spark.rdd.operator.transform

import org.apache.spark.{SparkConf, SparkContext}
import org.apache.spark.rdd.RDD

object Spark08_RDD_Operator_Transform {
  def main(args: Array[String]): Unit = {
    //准备环境
    val sparkConf = new SparkConf().setMaster("local[*]").setAppName("RDD")
    val sc = new SparkContext(sparkConf)
    //创建RDD
    val rdd:RDD[Int] = sc.makeRDD(List(1,2,3,4,5,6,7,8,9,10))
    //sample算子需要传递三个参数
    //1.第一个参数表示,抽取数据后是否将数据返回true(放回),false(丢弃)
    //2.第二个参数表示,
    //        如果抽取不放回的场合:数据源中每条数据被抽取的概率:基准值的概念
    //        如果抽取放回的场合,表示数据源中的每条数据被抽取的可能次数
    //3.第三个参数表示,抽取数据时随机算法的种子
    //                 如果不传递第三个参数,那么使用的是当前系统时间
    println(rdd.sample(
      false,
      fraction = 0.4,    //每个值的概率,并不一定是10条数据,一定会抽出四条数据
      seed = 1
    ).collect().mkString(","))
    //关闭环境
    sc.stop()
  }
}

        2.13:distinct:去重

package com.atguigu.bigdata.spark.rdd.operator.transform

import org.apache.spark.{SparkConf, SparkContext}
import org.apache.spark.rdd.RDD

object Spark09_RDD_Operator_Transform {
  def main(args: Array[String]): Unit = {
    //准备环境
    val sparkConf = new SparkConf().setMaster("local[*]").setAppName("RDD")
    val sc = new SparkContext(sparkConf)
    //创建RDD
    val rdd:RDD[Int] = sc.makeRDD(List(1,2,3,4,1,2,3,4))
    val rdd1:RDD[Int] = rdd.distinct()

    rdd1.collect().foreach(println)

    //关闭环境
    sc.stop()
  }
}

        2.14:coalesce:过滤完之后,可能分区内的数据会减少很多,避免资源浪费,可以根据数据量缩减分区,用于大数据集过滤后,提高小数据集的执行效率。。

package com.atguigu.bigdata.spark.rdd.operator.transform

import org.apache.spark.{SparkConf, SparkContext}
import org.apache.spark.rdd.RDD

object Spark10_RDD_Operator_Transform {
  def main(args: Array[String]): Unit = {
    //准备环境
    val sparkConf = new SparkConf().setMaster("local[*]").setAppName("RDD")
    val sc = new SparkContext(sparkConf)
    //创建RDD
    val rdd:RDD[Int] = sc.makeRDD(List(1,2,3,4,5,6),3)

    //coalesce:默认不会将数据打乱重新组合,不会将之前所在同一分区的数据,分配到不同的分区
    //这种情况下的缩减分区可能会导致数据不均衡,出现数据倾斜
    //如果想要让数据均衡,可以使用shuffle,第二个参数代表使用shuffle
    val newRDD:RDD[Int] = rdd.coalesce(2,true)
    newRDD.saveAsTextFile("output")
    //关闭环境
    sc.stop()
  }
}

        2.15:repartition:扩大分区


package com.atguigu.bigdata.spark.rdd.operator.transform

import org.apache.spark.{SparkConf, SparkContext}
import org.apache.spark.rdd.RDD

object Spark11_RDD_Operator_Transform {
  def main(args: Array[String]): Unit = {
    //准备环境
    val sparkConf = new SparkConf().setMaster("local[*]").setAppName("RDD")
    val sc = new SparkContext(sparkConf)
    //创建RDD
    val rdd:RDD[Int] = sc.makeRDD(List(1,2,3,4,5,6),2)

    //coalesce:可以扩大分区,但是需要注意一下,扩大分区是否要重新打乱,如果需要,需要将第二个参数改为true,使用shuffle
    val newRDD:RDD[Int] = rdd.repartition(3)
    newRDD.saveAsTextFile("output")
    //关闭环境
    sc.stop()
  }
}

        2.16:sortby:默认

package com.atguigu.bigdata.spark.rdd.operator.transform

import org.apache.spark.{SparkConf, SparkContext}
import org.apache.spark.rdd.RDD

object Spark12_RDD_Operator_Transform {
  def main(args: Array[String]): Unit = {
    //准备环境
    val sparkConf = new SparkConf().setMaster("local[*]").setAppName("RDD")
    val sc = new SparkContext(sparkConf)
    //创建RDD
    val rdd:RDD[Int] = sc.makeRDD(List(6,2,4,5,3,1),2)
    //sortby默认为升序,第二个参数可以改变排序的方式
    //sortby默认情况下,不会改变分区,但是中间存在shuffle操作
    val newRDD:RDD[Int] = rdd.sortBy(num=>num)
    newRDD.saveAsTextFile("output")
    //关闭环境
    sc.stop()
  }
}

         2.17:双value类型:交集,并集,差集和拉链

package com.atguigu.bigdata.spark.rdd.operator.transform

import org.apache.spark.{SparkConf, SparkContext}
import org.apache.spark.rdd.RDD

object Spark13_RDD_Operator_Transform {
  def main(args: Array[String]): Unit = {
    //准备环境
    val sparkConf = new SparkConf().setMaster("local[*]").setAppName("RDD")
    val sc = new SparkContext(sparkConf)
    //创建RDD    双value类型的操作,两个rdd
    val rdd1 = sc.makeRDD(List(1,2,3,5))
    val rdd2 = sc.makeRDD(List(3,4,5,6))

    //交集、并集、差集需要将两个数据源数据类型保持一致
    //拉链操作可以两个数据源数据类型不一致,拉链要求两个数据源的分区数量保持一致,数据源中的内容也要保持一致
    //交集[3,4]
    val rdd3:RDD[Int] = rdd1.intersection(rdd2)
    println(rdd3.collect().mkString(","))
    //并集[1,2,3,4,3,4,5,6]
    val rdd4:RDD[Int] = rdd1.union(rdd2)
    println(rdd4.collect().mkString(","))
    //差集rdd1的角度===>[1,2]
    val rdd5:RDD[Int] = rdd1.subtract(rdd2)
    println(rdd5.collect().mkString(","))
    //拉链[1-3,2-4,3-5,4-6]
     val rdd6:RDD[(Int, Int)] = rdd1.zip(rdd2)
    println(rdd6.collect().mkString(","))

    //关闭环境
    sc.stop()
  }
}

        2.18:键值类型:paritionby。分区器,改变数据存放的位置。

package com.atguigu.bigdata.spark.rdd.operator.transform

import org.apache.spark.{HashPartitioner, SparkConf, SparkContext}
import org.apache.spark.rdd.RDD

object Spark14_RDD_Operator_Transform {
  def main(args: Array[String]): Unit = {
    //准备环境
    val sparkConf = new SparkConf().setMaster("local[*]").setAppName("RDD")
    val sc = new SparkContext(sparkConf)
    //创建RDD    双value类型的操作,两个rdd
    val rdd = sc.makeRDD(List(1,2,3,4),2)

    val mapRDD = rdd.map((_,1))
    mapRDD.partitionBy(new HashPartitioner(2))
        .saveAsTextFile("output")

    //关闭环境
    sc.stop()
  }
}

        2.19:reduceByKey:相同的key数据,进行value数据的聚合操作

package com.atguigu.bigdata.spark.rdd.operator.transform

import org.apache.spark.{HashPartitioner, SparkConf, SparkContext}

object Spark15_RDD_Operator_Transform {
  def main(args: Array[String]): Unit = {
    //准备环境
    val sparkConf = new SparkConf().setMaster("local[*]").setAppName("RDD")
    val sc = new SparkContext(sparkConf)
    //创建RDD    双value类型的操作,两个rdd
    val rdd = sc.makeRDD(List(("a",1),("a",2),("a",3),("a",4)))
    //相同的key的数据,进行value数据的聚合操作
    //reduceByKey中如果key的数据只有一个,是不会参与运算的
    val reduceRDD = rdd.reduceByKey((x:Int,y:Int) => {x+y})

    reduceRDD.collect().foreach(println)
    //关闭环境
    sc.stop()
  }
}

        2.20:groupByKey:将数据源中的数,相同key的数据分在一个组中,形成一个对偶元组

package com.atguigu.bigdata.spark.rdd.operator.transform

import org.apache.spark.rdd.RDD
import org.apache.spark.{SparkConf, SparkContext}

object Spark16_RDD_Operator_Transform {
  def main(args: Array[String]): Unit = {
    //准备环境
    val sparkConf = new SparkConf().setMaster("local[*]").setAppName("RDD")
    val sc = new SparkContext(sparkConf)
    //创建RDD    双value类型的操作,两个rdd
    val rdd = sc.makeRDD(List(("a",1),("a",2),("a",3),("b",4)))

    //groupByKey:将数据源中的数据,相同key的数据分在一个组中,形成一个对偶元组
    // 元组中的第一个元素就是key,元组中的第二个元素就是相同的key的value的集合
    val groupRDD:RDD[(String,Iterable[Int])] = rdd.groupByKey()
    groupRDD.collect().foreach(println)
    //关闭环境
    sc.stop()
  }
}

        2.21:reduceByKey和groupByKey的区别

性能:reduceByKey优于groupByKey
    reduceByKey支持分区内预聚合的功能,可以有效减少shuffle时落盘的数据量
功能:groupByKey优于reduceByKey
    假如说只需要分组,不需要聚合

spark-day03-核心编程-RDD算子_第2张图片

spark-day03-核心编程-RDD算子_第3张图片

         2.22: aggregateByKey:分区内和分区间可以分离开进行不同的操作

package com.atguigu.bigdata.spark.rdd.operator.transform

import org.apache.spark.{SparkConf, SparkContext}
import org.apache.spark.rdd.RDD

object Spark17_RDD_Operator_Transform {
  def main(args: Array[String]): Unit = {
    //准备环境
    val sparkConf = new SparkConf().setMaster("local[*]").setAppName("RDD")
    val sc = new SparkContext(sparkConf)
    //创建RDD    双value类型的操作,两个rdd
    val rdd = sc.makeRDD(List(("a",1),("a",2),("a",3),("b",4)),2)
    //aggregateByKey存在函数柯里化,有两个参数列表
    //第一个参数列表,需要传递一个参数,表示为初始值
    //    主要用于当碰见第一个key的时候,和value进行分区内计算
    //第二个参数列表需要传递2个参数
    //    第一个参数表示分区内计算规则
    //    第二个参数表示分区间计算规则

    rdd.aggregateByKey(0)(
      (x,y) => math.max(x,y),
      (x,y) => x + y
    ).collect.foreach(println)


    //关闭环境
    sc.stop()
  }
}

spark-day03-核心编程-RDD算子_第4张图片

 spark-day03-核心编程-RDD算子_第5张图片

         2.23:foldByKey:分区内和分区间计算规则相同

package com.atguigu.bigdata.spark.rdd.operator.transform

import org.apache.spark.{SparkConf, SparkContext}

object Spark17_RDD_Operator_Transform2 {
  def main(args: Array[String]): Unit = {
    //准备环境
    val sparkConf = new SparkConf().setMaster("local[*]").setAppName("RDD")
    val sc = new SparkContext(sparkConf)
    //创建RDD    双value类型的操作,两个rdd
    val rdd = sc.makeRDD(List(("a",1),("a",2),("b",3),("b",4),("b",5),("a",6)),2)
    rdd.foldByKey(0)(_+_).collect.foreach(println)
    //关闭环境
    sc.stop()
  }
}

        2.24:combineByKey 

spark-day03-核心编程-RDD算子_第6张图片

val list: List[(String, Int)] = List(("a", 88), ("b", 95), ("a", 91), ("b", 93),
("a", 95), ("b",
val input: RDD[(String, Int)] = sc.makeRDD(list, 2)
val combineRdd: RDD[(String, (Int, Int))] = input. combineByKey
(_,
(acc: (Int, Int), v) => (acc._1 + v, acc._2 +
(acc1: (Int, Int), acc2: (Int, Int)) => (acc1._1 + acc2._1, acc1._2 + acc2._

        2.25:reduceByKey、foldByKey、aggregateByKey、combineByKey的区别

reduceByKey: 相同key的第一个数据不进行任何计算,分区内和分区间计算规则相同
FoldByKey: 相同key的第一个数据和初始值进行分区内计算,分区内和分区间计算规则相同

AggregateByKey:相同key的第一个数据和初始值进行分区内计算,分区内和分区间计算规则可以不相同
CombineByKey:当计算时,发现数据结构不满足要求时,可以让第一个数据转换结构。分区内和分区间计算规则不相同。

        2.26:join:两个不同数据源的数据,相同key的value会连接在一起,形成元组

package com.atguigu.bigdata.spark.rdd.operator.transform

import org.apache.spark.rdd.RDD
import org.apache.spark.{SparkConf, SparkContext}

object Spark19_RDD_Operator_Transform {
  def main(args: Array[String]): Unit = {
    val sparkConf = new SparkConf().setMaster("local[*]").setAppName("RDD")
    val sc = new SparkContext(sparkConf)
    //创建RDD    双value类型的操作,两个rdd
    val rdd1 = sc.makeRDD(List(("a",1),("b",2),("c",3)))

    val rdd2 = sc.makeRDD(List(("b",4),("c",5),("a",6)))

    //join:两个不同数据源的数据,相同的key的value会连接在一起,形成元组
    // 如果两个数据源中的key没有匹配上,那么数据不会出现在结果中,一个数据源中有m条,一个数据源中有n条,匹配次数为n*m
    val joinRDD: RDD[(String, (Int, Int))] = rdd1.join(rdd2)

    joinRDD.collect().foreach(println)
    //关闭环境
    sc.stop()
  }
}

        2.27:left outer join:类似于sql的左外连接      //  right outer join

package com.atguigu.bigdata.spark.rdd.operator.transform

import org.apache.spark.{SparkConf, SparkContext}
import org.apache.spark.rdd.RDD

object Spark20_RDD_Operator_Transform {
  def main(args: Array[String]): Unit = {
    val sparkConf = new SparkConf().setMaster("local[*]").setAppName("RDD")
    val sc = new SparkContext(sparkConf)
    //创建RDD    双value类型的操作,两个rdd
    val rdd1 = sc.makeRDD(List(("a",1),("b",2),("c",3)))

    val rdd2 = sc.makeRDD(List(("a",4),("b",5)))

    val joinRDD = rdd1.leftOuterJoin(rdd2)

    joinRDD.collect().foreach(println)
    //关闭环境
    sc.stop()
  }
}

        2.28:cogroup:同个数据源中相同key放在一组中,然后再和其他数据源中连接起来

package com.atguigu.bigdata.spark.rdd.operator.transform

import org.apache.spark.{SparkConf, SparkContext}

object Spark21_RDD_Operator_Transform {
  def main(args: Array[String]): Unit = {
    val sparkConf = new SparkConf().setMaster("local[*]").setAppName("RDD")
    val sc = new SparkContext(sparkConf)
    //创建RDD    双value类型的操作,两个rdd
    val rdd1 = sc.makeRDD(List(("a",1),("b",2)))

    val rdd2 = sc.makeRDD(List(("a",4),("b",5),("c",6),("c",7)))

    // cogroup connect + group  通个数据源中的  相同的key放在一个组中,然后再和其他数据源中连接起来
    val cgRDD = rdd1.cogroup(rdd2)
    cgRDD.collect().foreach(println)
    //关闭环境
    sc.stop()
  }
}

        2.29:collect

package com.atguigu.bigdata.spark.rdd.operator.action

import org.apache.spark.{SparkConf, SparkContext}

object Spark01_RDD_Operator_Action {
  def main(args: Array[String]): Unit = {
    val sparkConf = new SparkConf().setMaster("local[*]").setAppName("RDD")
    val sc = new SparkContext(sparkConf)

    val rdd = sc.makeRDD(List(1,2,3,4))
    //行动算子    触发作业(job)执行的方法
    rdd.collect()
    //底层代码,调用环境对象的runJob方法
    //底层代码中会创建ActiveJob,并提交执行
    sc.stop()
  }
}

        2.30:行动算子

package com.atguigu.bigdata.spark.rdd.operator.action

import org.apache.spark.{SparkConf, SparkContext}

object Spark02_RDD_Operator_Action {
  def main(args: Array[String]): Unit = {
    val sparkConf = new SparkConf().setMaster("local[*]").setAppName("RDD")
    val sc = new SparkContext(sparkConf)

    val rdd = sc.makeRDD(List(1,2,3,4))
   /* //行动算子reduce  聚集rdd中所有的元素,先聚合分区内的数据,再聚合分区间的数据
    val i = rdd.reduce(_+_)
    println(i)  //  10*/

    //collect,将不同分区的数据按分区顺序,以数组array的形式返回数据集的所有元素
    /*rdd.collect().foreach(println)*/

    //count:数据源中数据的个数
    val cnt = rdd.count()
    println(cnt)

    //first:获取数据源中数据的第一个
    val first = rdd.first()
    println(first)

    //获取数据源中前三个数据
    val ints = rdd.take(3)
    println(ints.mkString(","))

    //排完序之后,取前三个,从小到大排序
    val ints1 = rdd.takeOrdered(3)
    println(ints1.mkString(","))
    sc.stop()
  }
}

        2.31:行动算子-aggregate

package com.atguigu.bigdata.spark.rdd.operator.action

import org.apache.spark.{SparkConf, SparkContext}

object Spark03_RDD_Operator_Action {
  def main(args: Array[String]): Unit = {
    val sparkConf = new SparkConf().setMaster("local[*]").setAppName("RDD")
    val sc = new SparkContext(sparkConf)

    val rdd = sc.makeRDD(List(1,2,3,4),2)
    //aggregateByKey:初始值只会参与分区内计算
    //aggregate:初始值会参与分区内计算,并且会参与分区间计算
    val i = rdd.aggregate(10)(_+_,_+_)
    println(i)
    sc.stop()
  }
}

        2.32:行动算子-countByKey和countByValue

package com.atguigu.bigdata.spark.rdd.operator.action

import org.apache.spark.{SparkConf, SparkContext}

object Spark05_RDD_Operator_Action {
  def main(args: Array[String]): Unit = {
    val sparkConf = new SparkConf().setMaster("local[*]").setAppName("RDD")
    val sc = new SparkContext(sparkConf)

   // val rdd = sc.makeRDD(List(1,2,3,4),2)

    val rdd = sc.makeRDD(List(("a",1),("a",1),("a",1)))


    //countByValue:统计值出现的次数
   // val intToLong = rdd.countByValue()

    //countByKey:统计key出现的次数
   val intToLong = rdd.countByKey()
    println(intToLong)
    sc.stop()
  }
}

        2.33-行动算子-save

package com.atguigu.bigdata.spark.rdd.operator.action

import org.apache.spark.{SparkConf, SparkContext}

object Spark06_RDD_Operator_Action {
  def main(args: Array[String]): Unit = {
    val sparkConf = new SparkConf().setMaster("local[*]").setAppName("RDD")
    val sc = new SparkContext(sparkConf)

    val rdd = sc.makeRDD(List(("a",1),("a",2),("a",3)))
    rdd.saveAsTextFile("output")
    rdd.saveAsObjectFile("output1")
    // saveAsSequenceFile  要求数据的格式必须为key-value类型才能用这个方法
    rdd.saveAsSequenceFile("output2")
    sc.stop()
  }
}

        2.34-行动算子-foreach

package com.atguigu.bigdata.spark.rdd.operator.action

import org.apache.spark.{SparkConf, SparkContext}

object Spark07_RDD_Operator_Action {
  def main(args: Array[String]): Unit = {
    val sparkConf = new SparkConf().setMaster("local[*]").setAppName("RDD")
    val sc = new SparkContext(sparkConf)

    val rdd = sc.makeRDD(List(1,2,3,4))

    rdd.collect().foreach(println)  //再driver端内存集合的循环遍历方法
    println("-------")
    rdd.foreach(println)  //executor端,内存数据打印,无顺序概念

    sc.stop()
  }
}

spark-day03-核心编程-RDD算子_第7张图片

spark-day03-核心编程-RDD算子_第8张图片 

 

你可能感兴趣的:(spark,spark,大数据,big,data)