Spark mapPartitions算子使用方式

正常情况下我们使用map方法就足够了,一是使用简单,二是较为安全,mapPartitions在数据量很大的时候相当容易OOM,甚至是导致频繁GC,当然如果你资源足够且map方法对于你确实是效率不佳,那可以考虑使用mapPartitions

首先先要知道mapPartitionsmap有什么区别,map是直接处理单一的数据并返回,而mapPartitions是处理一个分区下的所有数据,并且它拿到的处理返回值必须是一个容器的迭代器

下面开一个实例

object Test {
  def main(args: Array[String]): Unit = {
    val session = SparkSession.builder().master("local[*]").appName("loadTest").getOrCreate()
    session.sparkContext.setLogLevel("ERROR")
    val sc = session.sparkContext

    val a = sc.parallelize(1 to 5)

    val result = a.mapPartitions(iter => {
      val res:scala.collection.mutable.ListBuffer[Int] = scala.collection.mutable.ListBuffer[Int]()
      while (iter.hasNext)
      {
        val cur = iter.next;
        res.insert(0,cur*3) ;
      }
      
      //返回容器的迭代器
      res.iterator
    })

    println(result.collect().mkString(","))
    session.stop()
  }
}

总体来说mapPartitions方法使用不困难,但是大家在实际开发中不要使用样例中的这种写法,这种写法是为了大家容易吸收,虽然我用了可变List,避免了不可变List的重复创建开销,不过在实际开发中,有一种高效的写法

object Test {
  def main(args: Array[String]): Unit = {
    val session = SparkSession.builder().master("local[*]").appName("loadTest").getOrCreate()
    session.sparkContext.setLogLevel("ERROR")
    val sc = session.sparkContext

    val a = sc.parallelize(1 to 5)

    val result = a.mapPartitions(r => new CustomIterator(r))

    println(result.collect().mkString(","))
    session.stop()
  }
}

class CustomIterator(iter: Iterator[Int]) extends Iterator[Int] {
  def hasNext : Boolean = {
    iter.hasNext
  }

  def next : Int= {

    val cur = iter.next

    cur
  }
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值