Spark算子

82 阅读3分钟

RDD转换算子

value类型

1.map

将处理的数据逐条进行映射转换,可以是类型的转换也可以是值的转换。如

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

val mapRdd = rdd.map(
  num => {
    println("num = " + num)
    num
  }
)

val mapRdd1: RDD[(Int, Int)] = mapRdd.map(
  num => {
    println("num1 = " + num)
    (num, 1)
  }
)

2.mapPartitions

以分区为单位对数据转换操作,会将整个分区的数据加载到内存中进行引用,map算子是类似串行的操作,性能比较低,mapPartitions算子是类似批处理,性能比较高,但是mapPartitions算子会长时间占用内存,在内存较小数据较大的情况下,可能会出现内存溢出的情况。

//    TODO算子 -mapPartitions
val rdd = sc.makeRDD(List(1,2,3,4),2)
    
val mapRdd = rdd.mapPartitions(
  iter => {
    println("-------------")
    iter.map(_ * 2)
  }
)

mapPartitions算子需要传递一个迭代器,返回一个迭代器,没有要求元素的个数不变,所以可以增加或是减少数据。

//    TODO算子 -mapPartitions
    val rdd = sc.makeRDD(List(1,2,3,4),2)

    val mpRdd = rdd.mapPartitions(
      iter => {
        List(iter.max).iterator//求出分区的最大值并转换为新的迭代器
      }
    )

    mpRdd.collect().foreach(println)
    println(mpRdd.getClass) //获取mpRdd的类

    sc.stop()

3.mapPartitionsWithIndex

将待处理的数据以分区为代为发送到计算节点进行处理,在处理的同时可以获得当前分区索引

//    TODO算子 -mapPartitionsWithIndex
    val rdd = sc.makeRDD(List(1,2,3,4))

    var mpiRDD = rdd.mapPartitionsWithIndex(
      (index, iter) =>{
        iter.map(
          num => {
            (num, index)
          }
        )
      }
    )


    mpiRDD.collect().foreach(println)

4.flatMap

将处理的数据进行扁平化后再进行映射处理

val dataRDD = sparkContext.makeRDD(List(
    List(1,2),List(3,4)
),1)

val dataRDD1 = dataRDD.flatMap(
    list => list
)
print("---------------------------------")

val rdd = sc.makeRDD(
  List("hello scala","hello spark")
)

val flatRDD: RDD[String] = rdd.flatMap(
  s => {
    s.split(" ")
  }
)

5.glom

将同一个分区的数据直接转换为相同类型的内存数组进行处理,分区不变

val rdd: RDD[Int] = sc.parallelize(List(1, 2, 3, 4), 2)

val glomRDD: RDD[Array[Int]] = rdd.glom()
//结果:ArrayBuffer(Array(1, 2), Array(3, 4))

val maxRDD: RDD[Int] = glomRDD.map(
  array => {
    array.max
  }
)

println(maxRDD.collect().sum)

6.groupBy

根据指定规则进行分组,根据分组的key进行分组,相同的key的数据会放在一个组中,分区规则默认不变,数据会打乱重新组合,存在shuffer过程

  val rdd = sc.makeRDD(List("hello","spark","scala","hadoop"),1)

    val groupRDD: RDD[(Char, Iterable[String])] = rdd.groupBy(_.charAt(0))


    groupRDD.saveAsTextFile("output")

7.filter

根据指定的规则进行筛选过滤,符合规则的数据保留否则丢弃,数据过滤后分区不变,但是分区的数据可能不均衡,可能会出现数据倾斜

//    TODO算子 -filter

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

    val filterRDD: RDD[Int] = rdd.filter(_ % 2 == 0)

    filterRDD.collect().foreach(println)
    sc.stop()

8.sample

根据指定的规则从数据集中抽取数据。需要传递三个参数,第一个参数表示抽取后是否放回,true(放回),false(不放回),第二个参数表示数据源中每条数据被抽取的概率,第三个参数表示,抽取数据时随机算法的种子

    val rdd = sc.makeRDD(List(1,2,3,4,5,6,7,8))

//  sample需要传递三个参数
//  第一个参数表示抽取数据后是否放回,true(放回),false(不放回)
//  第二个参数表示数据源中每条数据被抽取的概率
//   第三个参数表示,抽取数据时随机算法的种子

    println(rdd.sample(
      false,
      0.4
//      1
    ).collect().mkString(","))


    sc.stop()

9.distinct

很简单,将数据集中重复的数据去重

//    TODO算子 -distinct
    val rdd = sc.makeRDD(List(1,2,3,4,2,4,6))

    val rdd1: RDD[Int] = rdd.distinct(2)

    rdd1.collect().foreach(s => println(s*2))

10.coalesce

缩减分区,根据数据量缩减分区,用于大数据集过滤,提高小数据集的执行效率,在spark中存在过多小任务的时候可以使用coalesce方法,收缩合并分区,减少分区个数,减小任务调度成本

//    TODO算子 -coalesce
    val rdd = sc.makeRDD(List(1,2,3,4,5,6),3)

//    val newRDD: RDD[Int] = rdd.coalesce(2)

    val newRDD: RDD[Int] = rdd.coalesce(2,true)


    newRDD.saveAsTextFile("output11")