Spark中的map相关的算子以及区别

Spark中map相关算子及区别

  1. map算子:map[U](f: (T) => U): RDD[U]
    是对RDD中的每个元素都执行一个指定的函数开产生一个新的RDD。
    示例:
val conf = new SparkConf().setAppName("WC").setMaster("local[*]")

val sc = new SparkContext(conf)

val lineRDD = sc.makeRDD(1 to 10)
      .map(data => {
        data * 2
      })
    
lineRDD.foreach(println)

sc.stop()

结果:

6
12
8
14
10
2
4
20/05/21 11:01:30 INFO Executor: Running task 3.0 in stage 0.0 (TID 3)
16
18
20
  1. flatMap算子:flatMap[U](f: (T) => TraversableOnce[U]): RDD[U]
    类似于map,每一个输入元素可以被映射为0个或多个输出元素,相当于扁平化操作
    示例:
val listRDD: RDD[List[Int]] = sc.makeRDD(Array(List(1, 2, 3, 4, 5), List(6, 7, 8, 9, 10)))

val value: RDD[Int] = listRDD.flatMap(datas => datas.map(_ * 2))

value.foreach(println)

结果:

12
14
16
18
20
2
4
6
8
10

将list集合中的数据进行扁平化操作,最后输出。

  1. mapPartitions算子:mapPartitions[U](f: (Iterator[T]) => Iterator[U], preservesPartitioning: Boolean = false): RDD[U]
    与map算子类似,但能够独立的在RDD的每一个分片上运行,因此在类型为T的RDD上运行时,func的函数类型必须是Iterator[T] => Iterator[U]。假设有N个元素,有M个分区,那么map的函数的将被调用N次,而mapPartitions被调用M次,一个函数一次处理所有分区。
    示例:
val listRDD = sc.makeRDD(1 to 10)

val mapPartition = listRDD.mapPartitions(datas => datas.map(_ * 2))

mapPartition.collect().foreach(println)

sc.stop()

结果:

2
4
6
8
10
12
14
16
18
20

分析:从上面的结果来看,mapPartitions算子看似与map一样,但是如果从底层的源码来看,还是有一定的区别的,我们知道,RDD中有map,同样在Scala中也有map,我们打开mapPartitions的源码

  def mapPartitions[U: ClassTag](
      f: Iterator[T] => Iterator[U],
      preservesPartitioning: Boolean = false): RDD[U] = withScope {
    val cleanedF = sc.clean(f)
    new MapPartitionsRDD(
      this,
      (context: TaskContext, index: Int, iter: Iterator[T]) => cleanedF(iter),
      preservesPartitioning)
  }

这里面的参数是Interator,而Interator是Scala中可迭代的集合,所以代码中datas => datas.map(_ * 2)是Scala中的map操作,不是RDD中的map算子。在RDD的map中,计算的操作是_*2,计算在Executor中执行,所master会把10个数据分给不同的Executor执行,这样就会消耗大量的时间。而在mapPartitions中因为map是属于Scala的,所以datas.map(_ * 2)这样的整体是一个计算操作,所以master会把这样的整体发给Executor中,而datas是每一块分区的数据,所以mapPartitions算子会对每一块分区进行数据,这样会减少网络资源的消耗,效率优于map算子。
缺点:如果一个partition有很多数据的话,由于计算过后,会存在引用,所以内存不会释放,这样就可能会导致OOM。普通的map一般不会。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值