主要区别:
map是对rdd中的每一个元素进行操作;
mapPartitions则是对rdd中的每个分区的迭代器进行操作,可能导致OOM(OOM,全称“Out Of Memory”,翻译成中文就是“内存用完了”,来源于java.lang.OutOfMemoryError。)
PartitionMap的优点:
如果是普通的Map,比如一个partition中有一万条数据,那么你的function要执行和计数一万次
如果是使用PartitionMap,一个task仅仅会执行一次function,function一次接受所有的partition数据,只要执行一次就够了,性能相对来说比较高,如果在map过程中需要频繁创建额外的对象(例如将rdd中的数据通过jdbc写入数据库,map需要为每个元素创建一个链接而mapPartition为每个partition创建一个链接)则mapPartition效率比map高得多(SparkSql或DATAFrame默认会对程序进行mapPartition的优化)
PartitionMap的缺点
如果是普通的map操作,一次function的执行就处理一条数据;那么如果内存不够用的情况下, 比如处理了1千条数据了,那么这个时候内存不够了,那么就可以将已经处理完的1千条数据从内存里面垃圾回收掉,或者用其他方法,腾出空间来吧。
所以说普通的map操作通常不会导致内存的OOM异常。
但是MapPartitions操作,对于大量数据来说,比如甚至一个partition,100万数据,
一次传入一个function以后,那么可能一下子内存不够,但是又没有办法去腾出内存空间来,可能就OOM,内存溢出。
代码示例:
package zpark1128.pm
import org.apache.spark.rdd.RDD
import org.apache.spark.{
SparkConf, SparkContext}
object lianxiMapandMappartitions {
def main(args: Array[String]): Unit = {
val conf: SparkConf = new SparkConf().setMaster("local").setAppName("lianxiMapandMappartitions")
val sc = new