spark foreach与foreachPartition 详解

spark foreach与foreachPartition

每个partition中iterator时行迭代的处理,通过用户传入的function对iterator进行内容的处理

一:foreach的操作:
Foreach中,传入一个function,这个函数的传入参数就是每个partition中,每次的foreach得到的一个rdd的kv实例,也就是具体的内容
这种处理你并不知道这个iterator的foreach什么时候结果,只能是在foreach过程中,你得到一条数据,就处理一条数据
由下面的代码可以看出,foreach操作是直接调用了partition中数据的foreach操作

def foreach(f:Unit):Unit=withScope{
	val cleanF=sc.clean(f)
	sc.runJob(this,(iter:Iterator[t])=> iter.foreach(cleanF))
}

示例说明:

val list = new ArrayBuffer()
Rdd.foreach(record=>
	list+=record
	if(list.size>=10000){
		list.flush
	}
)

上面的这段示例代码,如果会存在一个问题,迭代的最后,list的结果可能还没有达到10000条,这个时候,你在内部处理的flush部分就不会执行,也就是迭代的最后如果没有迭代达到10000条的数据就会丢失,所以在foreach中,一般就是拿到一条数据进行处理
Rdd.foreach(
record._1 == a
return)

foreachPartition 操作

这个函数也是根据传入的function进行处理,但是不同之处再有这里function传入的参数是一个partition对应数据的iterator
而不是直接使用iterator的foreach,这种情况下,如果是上面foreach的示例代码中list这个片段在这个actition中就能够正常的去处理

def foreachPartition(f:Iterrator[T]=>Unit):Unit=withScope{
	val cleanF=sc.clean(f)
	sc.runJob(this,(iter:Itertor[T]=>cleanF(iter)))
}

示例

val list = new ArrayBuffer
rdd.foreachPartition(it=>{
it.foreach(r=>{
list+=r
if(list.size>10000)
flush
})
if(list.size>0)
flush
})

关于源码

可以看到方法通过clean操作(清理闭包,为序列化和网络传输做准备),进行了一次匿名函数的封装
针对foreach方法,是我们的方法被传入了迭代器foreach(每个元素执行一次函数)
而对于foreachPartition方法是迭代器被传入了我们的方法(每个分区执行一次函数,我们获取迭代器后需要自行进行迭代处理)

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值