繁体   English   中英

Spark Scala:此用例中的mapPartitions

[英]Spark Scala: mapPartitions in this use case

我在阅读有关map和mapPartitions之间的差异的内容很多。 我仍然有一些怀疑。 事情是在阅读之后,我决定在代码中更改mapPartitionsmap函数,因为显然mapPartitionsmap更快。

我的问题是要确定我的决定在以下情况下是否正确( 注释显示了先前的代码 ):

val reducedRdd = rdd.mapPartitions(partition => partition.map(r => (r.id, r)))
//val reducedRdd = rdd.map(r => (r.id, r))
.reduceByKey((r1, r2) => r1.combineElem(r2))
// .map(e => e._2)
.mapPartitions(partition => partition.map(e => e._2))

我在想对吗? 谢谢!

就您而言,mapPartitions应该没有任何区别。

mapPartitions与地图

当我们要对每个分区进行一些通用计算时,mapPartitions很有用。 范例-

rdd.mapPartitions{
  partition => 
    val complicatedRowConverter = <SOME-COSTLY-COMPUTATION>
    partition.map {
      row => (row.id, complicatedRowConverter(row) )
    }
}

在上面的示例中,我们正在创建一个complicatedRowConverter RowConverter函数,该函数是从一些昂贵的计算中衍生而来的。 此功能对于整个RDD分区都是相同的,我们不需要一次又一次地重新创建它。 做同一件事的另一种方法可以是-

rdd.map { row => 
      val complicatedRowConverter = <SOME-COSTLY-COMPUTATION>
      (row.id, complicatedRowConverter(row) )
    }
}

这将很慢,因为我们不必要为每行运行此语句val complicatedRowConverter = <SOME-COSTLY-COMPUTATION>

就您而言,每个分区都没有任何预计算或其他任何内容。 在mapPartition中,您只需遍历每行并将其映射到(row.id, row)

因此,这里的mapPartition不会受益,您可以使用简单的map。

tl; dr mapPartitions在这种情况下会很快。

为什么

考虑功能

def someFunc(row): row {
  // do some processing on row
  // return new row
}

假设我们正在处理100万条记录

地图

我们最终将其称为someFunc 100万。
创建了无序的1m虚拟函数调用和其他内核数据结构以进行处理

mapPartition

我们将其写为

mapPartition { partIter =>
  partIter.map {
    // do some processing on row
    // return new row
  }
}

没有虚拟功能,请在此处进行上下文切换。

因此, mapPartitions将更快。

另外,就像@ moriarity007的答案中提到的那样,在决定要使用的运算符之间时,我们还需要考虑操作涉及的对象创建开销。

另外,我建议使用数据帧转换和操作来进行处理,从而使计算速度更快,因为Spark催化剂可以优化您的代码,并且还可以利用代码生成的优势。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM