Spark中map与mapPartitions的区别详解-附测试

                                           今天也要努力学习

map与mapPartitions

    两者的主要区别是作用对象不一样:map的输入变换函数是应用于RDD中每个元素,而mapPartitions的输入函数是应用于每个分区。

    假设一个rdd有10个元素,分成3个分区。如果使用map方法,map中的输入函数会被调用10次;而使用mapPartitions方法的话,其输入函数会只会被调用3次,每个分区调用1次。

    场景举例:大数据集情况下的资源初始化开销和批处理处理,当方法需要初始化一个耗时的资源,然后使用,比如数据库连接。这个时候map需要根据rdd中的元素进行多次的数据库 的连接和关闭,这样就耗费了很多不必要的资源,而mapPartitions只需要针对分区进行资源的初始化连接,显然在大数据集情况下(数据集中元素个数远大于分区数),mapPartitons的开销要小很多,也便于进行批处理操作。

mapPartiton的优势:

    提高性能,比如我们对一个含有100条log数据的分区进行操作,使用map的话函数要执行100次计算。使用MapPartitions操作之后,一个task仅仅会执行一次function,function一次接收所有的partition数据。如果map执行的过程中还需要创建对象,比如创建jdbc连接等。map需要为每个元素创建一个链接而mapPartition为每个partition创建一个链接。

mapPartiton的缺点:

    对于一个partition有很多数据的话,一次函数处理可能会导致OOM。普通的map一般不会导致OOM。

举个虚拟场景操作的例子:

package com.wuyue.spark

import org.apache.spark.rdd.RDD
import org.apache.spark.sql.SparkSession

import scala.collection.mutable.{ArrayBuffer, ListBuffer}

/**
  * 测试mappartiton 和 foreachpartition  根据分区处理数据
  */
object mapPartition_foreachpartition {
  def main(args: Array[String]): Unit = {
    val  session = SparkSession.builder()
      .appName("wuyue")
      .master("local")
      .getOrCreate()
    val sc = session.sparkContext
    sc.setLogLevel("Error")
    val rdd1: RDD[String] = sc.parallelize(List[String]("1","11","111","2","22","222"),2)

    //这样的方式处理数据需要多次进行数据库的连接关闭,耗费资源
        rdd1.map(s=>{
          println("创建数据库连接。。。。。。。")
          println("数据库操作。。。。。。。"+s)
          println("关闭数据库连接。。。。。。。")
        }).count()   //用一个count来触发这个懒函数的执行

    /**
      * mappartition  传进去的是一个iterrator 传出来的也是一个iterator
      * 传进来的iter是根据分区进行遍历  一次分区创建一次对象
      * 一个分区传进一个迭代器。
      */
      rdd1.mapPartitions(iter=>{
      var list = ArrayBuffer[String]()
      println("创建数据库连接。。。。。。。。")
      while (iter.hasNext){
        val curr = iter.next()
        list.append(curr)
        println(s"$curr  数据库操作。。。。。")
      }
     println("关闭数据库连接=====")
     list.iterator
     }).count()

  }

}

map运行结果:

mapPartitions运行结果

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值