Spark 中的算子

本文详细介绍了Spark中的转换算子,包括map、mapPartitions、filter、groupBy等23种算子的用法和示例,帮助理解Spark数据处理过程。
摘要由CSDN通过智能技术生成

一、转换算子

value 类型:

1.1 map 算子

1、算子签名

def map[U: ClassTag](f: T => U): RDD[U]

2、算子说明

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

3、代码演示

package spark.core.conversion_operator.map

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

/**
 * map 算子介绍
 */
object Spark_RDD_Operator_Map_Study1 {
   
  def main(args: Array[String]): Unit = {
   
    val sparkConf = new SparkConf().
      setMaster("local[*]").
      set("spark.driver.host", "localhost").
      setAppName("rdd")
    val sc = new SparkContext(sparkConf)

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

    // 转换:旧 RDD -> 算子 -> 新 RDD
    // 简化过程:
//    var rdd1: RDD[Int] = rdd.map((i: Int) => {
   
//      i * 2
//    })
//    var rdd1: RDD[Int] = rdd.map((i: Int) => i * 2)
//    var rdd1: RDD[Int] = rdd.map((i) => i * 2)
//    var rdd1: RDD[Int] = rdd.map(i => i * 2)
    val rdd1: RDD[Int] = rdd.map(_ * 2)

    // 读取数据
    // collect 方法不回转换 RDD,会触发作业的执行,所以将 collect 这样的方法称为行动算子(action)。
    val ints: Array[Int] = rdd1.collect()
    for (elem <- ints) {
   
      print(elem + " ")
    }

    sc.stop()
  }
}

运算结果:
在这里插入图片描述

4、demo
(1) 说明
从日志数据中获取用户请求 URL 资源路径

(2) 数据

83.149.9.216 - - 17/05/2015:10:05:03 +0000 GET /presentations/logstash-monitorama-2013/images/kibana-search.png
83.149.9.216 - - 17/05/2015:10:05:43 +0000 GET /presentations/logstash-monitorama-2013/images/kibana-dashboard3.png
83.149.9.216 - - 17/05/2015:10:05:47 +0000 GET /presentations/logstash-monitorama-2013/plugin/highlight/highlight.js
83.149.9.216 - - 17/05/2015:10:05:12 +0000 GET /presentations/logstash-monitorama-2013/plugin/zoom-js/zoom.js
83.149.9.216 - - 17/05/2015:10:05:07 +0000 GET /presentations/logstash-monitorama-2013/plugin/notes/notes.js
83.149.9.216 - - 17/05/2015:10:05:34 +0000 GET /presentations/logstash-monitorama-2013/images/sad-medic.png
83.149.9.216 - - 17/05/2015:10:05:57 +0000 GET /presentations/logstash-monitorama-2013/css/fonts/Roboto-Bold.ttf
83.149.9.216 - - 17/05/2015:10:05:50 +0000 GET /presentations/logstash-monitorama-2013/css/fonts/Roboto-Regular.ttf
83.149.9.216 - - 17/05/2015:10:05:24 +0000 GET /presentations/logstash-monitorama-2013/images/frontend-response-codes.png
83.149.9.216 - - 17/05/2015:10:05:50 +0000 GET /presentations/logstash-monitorama-2013/images/kibana-dashboard.png
83.149.9.216 - - 17/05/2015:10:05:46 +0000 GET /presentations/logstash-monitorama-2013/images/Dreamhost_logo.svg
83.149.9.216 - - 17/05/2015:10:05:11 +0000 GET /presentations/logstash-monitorama-2013/images/kibana-dashboard2.png
83.149.9.216 - - 17/05/2015:10:05:19 +0000 GET /presentations/logstash-monitorama-2013/images/apache-icon.gif
83.149.9.216 - - 17/05/2015:10:05:33 +0000 GET /presentations/logstash-monitorama-2013/images/nagios-sms5.png
83.149.9.216 - - 17/05/2015:10:05:00 +0000 GET /presentations/logstash-monitorama-2013/images/redis.png
83.149.9.216 - - 17/05/2015:10:05:25 +0000 GET /presentations/logstash-monitorama-2013/images/elasticsearch.png
83.149.9.216 - - 17/05/2015:10:05:59 +0000 GET /presentations/logstash-monitorama-2013/images/logstashbook.png
83.149.9.216 - - 17/05/2015:10:05:30 +0000 GET /presentations/logstash-monitorama-2013/images/github-contributions.png
83.149.9.216 - - 17/05/2015:10:05:53 +0000 GET /presentations/logstash-monitorama-2013/css/print/paper.css
83.149.9.216 - - 17/05/2015:10:05:24 +0000 GET /presentations/logstash-monitorama-2013/images/1983_delorean_dmc-12-pic-38289.jpeg
83.149.9.216 - - 17/05/2015:10:05:54 +0000 GET /presentations/logstash-monitorama-2013/images/simple-inputs-filters-outputs.jpg
83.149.9.216 - - 17/05/2015:10:05:33 +0000 GET /presentations/logstash-monitorama-2013/images/tiered-outputs-to-inputs.jpg
83.149.9.216 - - 17/05/2015:10:05:56 +0000 GET /favicon.ico
24.236.252.67 - - 17/05/2015:10:05:40 +0000 GET /favicon.ico
93.114.45.13 - - 17/05/2015:10:05:14 +0000 GET /articles/dynamic-dns-with-dhcp/
93.114.45.13 - - 17/05/2015:10:05:04 +0000 GET /reset.css
93.114.45.13 - - 17/05/2015:10:05:45 +0000 GET /style2.css
93.114.45.13 - - 17/05/2015:10:05:14 +0000 GET /favicon.ico
93.114.45.13 - - 17/05/2015:10:05:17 +0000 GET /images/jordan-80.png
93.114.45.13 - - 17/05/2015:10:05:21 +0000 GET /images/web/2009/banner.png
66.249.73.135 - - 17/05/2015:10:05:40 +0000 GET /blog/tags/ipv6
50.16.19.13 - - 17/05/2015:10:05:10 +0000 GET /blog/tags/puppet?flav=rss20

(3) 代码

package spark.core.conversion_operator.map

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

/**
 * 使用 map 算子做的一个 demo,处理一下日志数据。
 */
object Spark_RDD_Operator_Map_Demo1 {
   
  def main(args: Array[String]): Unit = {
   
    val sparkConf = new SparkConf().
      setMaster("local[*]").
      set("spark.driver.host", "localhost").
      setAppName("rdd")
    val sc = new SparkContext(sparkConf)

    // 从日志数据中获取用户请求 URL 资源路径
    val fileRDD: RDD[String] = sc.textFile("input/apache.log")

    val urlRDD: RDD[String] = fileRDD.map(
      line => {
   
        var datas: Array[String] = line.split(" ")
        datas(6)
      }
    )
    urlRDD.collect().foreach(println)
    sc.stop()
  }
}

(4) 运行结果
在这里插入图片描述

1.2 mapPartitions 算子

1、算子签名

def mapPartitions[U: ClassTag](
    f: Iterator[T] => Iterator[U],
    preservesPartitioning: Boolean = false): RDD[U]

2、算子说明
将待处理的数据以分区为单位发送到计算节点进行处理,这里的处理是指可以进行任意的处理,哪怕是过滤数据。

3、代码演示

package spark.core.conversion_operator.mapPartitions

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

/**
 * mapPartitions 算子介绍
 */
object Spark_RDD_Operator_MapPartitions_Study1 {
   
  def main(args: Array[String]): Unit = {
   
    val sparkConf = new SparkConf().
      setMaster("local[*]").
      set("spark.driver.host", "localhost").
      setAppName("rdd")
    val sc = new SparkContext(sparkConf)

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

    // mapPartitions 是以分区作为单位进行计算,和 map 算子很像。
    // 区别就在于 map 算子是一个一个执行,而 mapPartitions 一个一个分区执行,类似于批处理。

    // map 方法是全量数据操作,不能丢失数据。
    // mapPartitions 方法是一次性获取分区的所有数据,那么可以执行迭代器集合的所有操作,
    // 比如:过滤、max、sum
    val rdd1: RDD[Int] = rdd.mapPartitions(
      iter => {
   
        iter.filter(_ % 2 == 0)
      }
    )

    val data: Array[Int] = rdd1.collect()
    println(data.mkString(","))
    println(data.toList)
    sc.stop()
  }
}

运算结果:
在这里插入图片描述

4、demo
(1) 说明
获取每个数据分区的最大值

(2) 代码

package spark.core.conversion_operator.mapPartitions

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

/**
 * mapPartitions 算子获取各个分区的最大值
 */
object Spark_RDD_Operator_MapPartitions_Demo1 {
   
  def main(args: Array[String]): Unit = {
   
    val sparkConf = new SparkConf().
      setMaster("local[*]").
      set("spark.driver.host", "localhost").
      setAppName("rdd")
    val sc = new SparkContext(sparkConf)

    val rdd: RDD[Int] = sc.makeRDD(List(1, 4, 3, 2, 5, 6), numSlices = 2)

    // 获取分区的最大值,第一个分区为 1 4 3,第二个分区为 2 5 6。
    val rdd1: RDD[Int] = rdd.mapPartitions(
      iter => {
   
        List(iter.max).iterator
      }
    )

    // map 与 mapPartitions 区别:
    // map 算子每一次处理一条数据,而 mapPartitions 算子每一次将一个分区的数据当成一个整体
    // 进行数据处理,如果一个分区的数据没有完全处理完,那么所有的数据都不会释放,即使当前面已经
    // 处理完的数据也不会释放。所以当内存空间足够大时,为了提高效率,推荐使用 mapPartitions
    // 算子。
    val data: Array[Int] = rdd1.collect()
    println(data.mkString(","))
    sc.stop()
  }
}

(3) 运算结果
在这里插入图片描述

1.3 mapPartitionsWithIndex 算子

1、算子签名

def mapPartitionsWithIndex[U: ClassTag](
  f: (Int, Iterator[T]) => Iterator[U],
  preservesPartitioning: Boolean = false): RDD[U]

2、算子说明
将待处理的数据以分区为单位发送到计算节点进行处理,这里的处理是指可以进行任意的处理,哪怕是过滤数据。在处理时同时可以获取当前分区索引。

3、代码演示

package spark.core.conversion_operator.mapPartitionsWithIndex

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

/**
 * mapPartitionsWithIndex 算子介绍
 */
object Spark_RDD_Operator_MapPartitionsWithIndex_Study1 {
   
  def main(args: Array[String]): Unit = {
   
    val sparkConf = new SparkConf().
      setMaster("local[*]").
      set("spark.driver.host", "localhost").
      setAppName("rdd")
    val sc = new SparkContext(sparkConf)

    val rdd: RDD[Int] = sc.makeRDD(List(5, 2, 3, 4), numSlices = 2)

    // 获取每个分区的最大值及分区号
    val rdd1: RDD[(Int, Int)] = rdd.mapPartitionsWithIndex(
      (index, iter) => {
   
        List((index, iter.max)).iterator
      }
    )

    println(rdd1.collect().mkString(","))
    sc.stop()
  }
}

运算结果:
在这里插入图片描述

4、demo
(1) 说明
获取第二个数据分区的数据

(2) 代码

package spark.core.conversion_operator.mapPartitionsWithIndex

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

/**
 * mapPartitionsWithIndex 算子介绍
 */
object Spark_RDD_Operator_MapPartitionsWithIndex_Demo1 {
   
  def main(args: Array[String]): Unit = {
   
    val sparkConf = new SparkConf().
      setMaster("local[*]").
      set("spark.driver.host", "localhost").
      setAppName("rdd")
    val sc = new SparkContext(sparkConf)

    val rdd: RDD[Int] = sc.makeRDD(List(5, 2, 3, 4), numSlices = 2)

    // 获取第二个分区的数据
    // Nil是一个空的List,定义为List[Nothing]
    val rdd2: RDD[Int] = rdd.mapPartitionsWithIndex(
      (index, iter) => {
   
        if (index == 1) {
   
          iter
        } else {
   
          // 空集合
          Nil.iterator
        }
      }
    )

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

(3) 运行结果
在这里插入图片描述

1.4 flatMap 算子

1、算子签名

def flatMap[U: ClassTag](f: T => TraversableOnce[U]): RDD[U]

2、算子说明
将处理的数据进行扁平化后再进行映射处理,所以算子也称之为扁平映射。

3、代码演示

package spark.core.conversion_operator.flatMap

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

/**
 * flatmap 算子的介绍:
 * 将处理的数据进行扁平化后再进行映射处理,所以算子也称之为扁平映射。
 */
object Spark_RDD_Operator_FlatMap_Study1 {
   
  def main(args: Array[String]): Unit = {
   
    val sparkConf = new SparkConf().
      setMaster("local[*]").
      set("spark.driver.host", "localhost").
      setAppName("rdd")
    val sc = new SparkContext(sparkConf)

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

    // flatmap() 是将函数应用于 RDD 中的每个元素,将返回的迭代器的所有内容构成新的 RDD。
    val rdd1: RDD[Int] = rdd.flatMap(
      list => list
    )

    println(rdd1.collect().mkString(","))

    sc.stop()
  }
}

运行结果:
在这里插入图片描述

4、demo
(1) 说明
对 List(List(1, 2), 3, List(4, 5)) 进行 flatMap

(2) 代码

package spark.core.conversion_operator.flatMap

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

/**
 * flatmap 算子的介绍:
 * 将处理的数据进行扁平化后再进行映射处理,所以算子也称之为扁平映射。
 */
object Spark_RDD_Operator_FlatMap_Demo1 {
   
  def main(args: Array[String]): Unit = {
   
    val sparkConf = new SparkConf().
      setMaster("local[*]").
      set("spark.driver.host", "localhost").
      setAppName("rdd")
    val sc = new SparkContext(sparkConf)

    // 将如下数据进行扁平化处理
    val rdd1: RDD[Any] = sc.makeRDD(
      List(List(
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值