spark在什么情况下会使用mapPartition

在spark中,map算子可以说是我们使用最频繁的一个基础算子,功能也非常简单,将一条数据经过变换形成另外一条数据。那么还有一个算子和它非常相似:mapPartition。
很显然,这个算子多了一个Partition,所以表示的含义就是:对于每一个分区的数据,整体进行数据的变换。
有人可能会问,难道map就不是对分区进行的?也是。不过map没有分区的概念,就是一条数据一条处理,也是分布式的处理,只是在map无法看到分区而已。
那么对于mapPartition算子,什么情况下会使用呢?这里例举两种最频繁的应用场景:
(1)数据频繁进行与外部交互的时候。
最典型的比如需要将分布式的数据data每条进行与数据库的增删改查操作。很自然的想法就是:

sc.parallelize(Seq(1, 2, 3, 4, 5))
.map{x =>
	XXX // 连接数据库操作
	XXX.insert(x) // 增删改查该数据到数据库
	XXX// 关闭数据库
x
}

很显然这里采用直白的map操作,那么每条数据都会进行一次数据库的连接与关闭操作,显然是没有必要的。试想一下,其实每个分区的数据都在同一台机器上,那么对这个机器上的数据,其实只需要做一次数据库的连接与关闭操作不就行了?

这就自然引出了mapPartition算子。mapPartition本身会将一个分区的数据打包成一个迭代器统一操作。
还是刚才的例子,那么伪代码就是:

sc.parallelize(Seq(1, 2, 3, 4, 5))
.mapPartitions{iter =>
	XXX // 连接数据库操作
	var res = List[Int]()
	while(iter.hasNext) {
	    val next = iter.next()
	    XXX.insert(next) // 增删改查该数据到数据库
	    res = res :+ next
	}
	XXX// 关闭数据库
	res.toIterator
}

可以看到,对于每一个分区的数据,只需要建立一次连接数据库,然后数据库变量可以对整个分区数据使用。mapPartitions传入的是整个分区数据,并且是个迭代器(Iterator),并且输出也得是迭代器,要不然会报错。
所以,如果某个函数需要对整个分区都生效,并且不需要频繁调用,都可以考虑mapPartitions。其他情况下,如果没有此类操作,那么多数时候还是map更好。

(2)数据需要在分区内先进行预处理的操作
简而言之就是:分区间需要各自独立计算(如扩充数据、删减数据、组合变换形成新数据等操作)然后输出

这种情况下通常是在优化任务性能的时候、或者分区间进行各自独立处理然后把结果汇总的时候会用到。

比如你有一个(k,v)形式的海量数据需要进行各种聚合等操作,但是k太多了你有不想要这么多的k数据,那么可以在聚合后的分区里面单独处理,使用filter过滤掉分区中的某些数据,也就是对分区自己进行某种形式的瘦身;

好了对于mapPartitions我觉得大多是情况下会在这两类应用场景使用较多。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值