Spark02--RDD算子

这篇博客详细介绍了Spark中的RDD算子,包括转换算子如map、filter、groupBy等,以及双value型操作和kv类型数据操作。同时,文章还讨论了行动算子如reduce、collect、count等功能,并解释了算子间的关系,如血缘关系和依赖关系,以及RDD的持久化机制如Cache和CheckPoint。
摘要由CSDN通过智能技术生成

1 RDD

        1.1 RDD分类和算子的基本概念
  • 什么是算子:RDD处理数据的方法。
  • 为什么要叫做算子: 为了和scala集合方法区分 因为scala集合方法在Driver端执行 而RDD的方法可在不同的Executor端执行

在这里插入图片描述

        1.2 转换算子–value型
  • map

    • 文本数据逐行转换 内存数据逐个转换
    • 分区内:一条数据执行完所有算子的逻辑后 下一条数据才开始执行
    • 分区间:并发执行 互不影响
  • mapParatition

    • 和map算子很像,区别在于map是一条一条执行 而该算子是以整个分区数据 为基本执行单位,在整个分区内做一些操作(整个分区的数据最为迭代器,因此可以调用一些迭代器的一些操作 最大值 最小值 )。如果分区数据未处理完 所有分区数据都不会释放 内存大推荐使用性能高 否则内存容易溢出。
   /**
      * 四个区
      * 第一个分区    5/4=1       arr[0]=2
      * 第二个分区    5*2/4       arr[1]=4
      * 第三个分区                arr[2]=1
      * 第四个分区    4*5/4=5     arr[3]=3
      *                          arr[4]=5
      */
    val rdd = sparkContext.makeRDD(List(2,4,1,3,5),4)
    val value = rdd.mapPartitions(iter => {
   
      // TODO iter表示每个分区的数据 可以调用迭代器的方法 例如最小最大值 过滤等
      println(iter.max)
      iter
    })
    println(value.collect().mkString("\n"))
  • mapPartitionsWithIndex:一个分区一个分区执行 分区内做一些操作,操作的同时获取分区号
// 分区号和 index 表示分区号 iter 表示分区的数据
val value = rdd.mapPartitionsWithIndex((index, iter) => {
   
  List((index, iter.max)).iterator
})
  • flatMap(fun):将集合中的元素打散成单独元素 每个元素执行fun函数。将所有的返回结果返回到一个集合中,返回结果的集合元素是一个一个基本类型 不能再是集合类型。
    • map和flaymap的区别见以下例子
    • map函数后,RDD的值为 Array(Array(“a”,“b”),Array(“c”,“d”),Array(“e”,“f”))
    • flatMap函数处理后,RDD的值为 Array(“a”,“b”,“c”,“d”,“e”,“f”)。即最终可以认为,flatMap会将其返回的数组全部拆散,然后合成到一个数组中

object MapAndFlatMap {
   
  def main(args: Array[String]): Unit = {
   
    val sc = new SparkContext(new SparkConf().setAppName("map_flatMap_demo").setMaster("local"))
    val arrayRDD =sc.parallelize(Array("a_b","c_d","e_f"))
    /**
    * a_b
    * c_d
    * e_f
    */
    arrayRDD.foreach(println) //打印结果1 

    arrayRDD.map(string=>{
   
      string.split("_")
    }).foreach(x=>{
   
    /**
    * a,b
    * c,d
    * e,f
    */
      println(x.mkString(",")) //打印结果2
    })

    arrayRDD.flatMap(string=>{
   
      string.split("_")
    }).foreach(x=>{
   
    
     /**
    * a,b,c,d,e,f
    *
    */
      println(x.mkString(","))//打印结果3
    })
  }
}


  • glom() :将分区数据转为数组
    在这里插入图片描述

  • filter:将数据根据指定的规则进行筛选过滤,符合规则的数据保留,不符合规则的数据丢弃。

  • groupBy :将数据根据指定的规则进行分组, 分区默认不变,但是数据会被打乱重新组合,我们将这样的操作称之为shuffle。极限情况下,数据可能被分在同一个分区中


/**
  * 根据单词的首写字母进行分组
  *
  */

object RDD_GroupBy {
   
  def main (args: Array[String] ): Unit = {
   
      val sparkContext = new SparkContext(new SparkConf().setMaster("local[*]").setAppName("RDD_GroupBy"))
      val rdd1 = sparkContext.makeRDD(List("Hello", "hive", "hbase", "Hadoop"),3)
    val rdd2 = rdd1.groupBy(x => {
   
      // 或者x(0)
      val str = x.toString.substring(0, 1)

      if ("H".equals(str)) {
   
        0
      } else if ("h".equals(str)) {
   
        1
      }

    })
    println(rdd2.collect().mkString(","))
}
}

  • sample:抽取数据 从数据倾斜的数据分区中抽取数据 看看是不是相同的数据太多了 后续再优化处理
/**
  * 随机数抽取
  * 参数1:是否放回
  * 参数2:被抽中的概率 2:表示被抽中的两次 至于一定能被抽中两次不一定 这只是表示概率
  * 参数3:随机数种子,随机算法都要一个初始值,如果没有一个初始值,
  * 他也不能凭空制造一系列的随机数出来,那我们说的随机种子seed()就是这是初始值。
  * 默认初始值是系统时间
  */

object RDD_Smaple {
   
  def main(args: Array[String]): Unit = {
   
    val sparkContext = new SparkContext(new SparkConf().setMaster("local[*]").setAppName("flatmap"))
    val value1 = sparkContext.makeRDD(List(1, 2, 3, 4, 5, 7, 8), 1)
    println(value1.sample(true, 2, 3).collect().mkString(","))

  }
}

  • distinct 数据去重 去重通过方法参数改变分区数量 因为去重后数据量变少
/**
  * 随机数抽取
  */

object RDD_Distinct {
   
  def main(args: Array[String]): Unit = {
   
    val sparkContext = new SparkContext(new SparkConf().setMaster("local[*]").setAppName("flatmap"))
    val value1 = sparkContext
      .makeRDD(List(1, 2, 1, 2, 3, 4, 3,4), 2)
      // 去重后改变分区
      .distinct(1)
    println(value1.collect().mkString(","))

    val value2 = sparkContext
      // 去重不改变分区
      .makeRDD(List(1, 2, 1, 2, 3, 4, 3,4), 2).distinct()
    println(value2.collect().mkString(","))
    
  }
}

  • coalesce:根据数据量缩减分区,用于大数据集过滤后,提高小数据集的执行效率.shuffer默认是false 不打乱数据重组。
  • repartition
    • 该操作内部其实执行的是coalesce操作,参数shuffle的默认值为true。无论是将分区数多的RDD转换为分区数少的RDD,还是将分区数少的RDD转换为分区数多的RDD,repartition操作都可以完成,因为无论如何都会经shuffle过程。
  • sortBy

def sortBy[K](
f: (T) => K,
ascending: Boolean = true,
numPartitions: Int = this.partitions.length)

  • 该操作用于排序数据。在排序之前,可以将数据通过f函数进行处理,之后按照f函数处理的结果进行排序,默认为正序排列。排序后新产生的RDD的分区数与原RDD的分区数一致。

val dataRDD = sparkContext.makeRDD(List(1,2,3,4,1,2),2)
val dataRDD1 = dataRDD.sortBy(num=>num, false, 4)

        1.3 RDD算子–双value型 两个RDD value型数据做操作
  • 交集 并集 差集 拉链

object RDD_OPOperator {
   
  def main (args: Array[String])
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值