避免使用GroupByKey

本文深入探讨了在Spark中使用reduceByKey和groupByKey进行WordCount操作时的性能差异,强调了reduceByKey在大规模数据集上的优势,并介绍了其他性能优化函数如combineByKey和foldByKey。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

有两种方法实现wordcount,一种是使用reduceByKey,另一种是使用groupByKey。

val words = Array("one", "two", "two", "three", "three", "three")
val wordPairsRDD = sc.parallelize(words).map(word => (word, 1))

val wordCountsWithReduce = wordPairsRDD
  .reduceByKey(_ + _)
  .collect()

val wordCountsWithGroup = wordPairsRDD
  .groupByKey()
  .map(t => (t._1, t._2.sum))
  .collect()

虽然两种方式都能得到正确的结果,但是在大规模数据集上,使用reduceByKey的性能更好。这是因为Spark知道在shuffle数据之前在每个partition上对数据按照统一的key进行结合。

reduceByKey的过程如下图所示:

ReduceByKey

可以看出shuffle过程的数据有(a,1),(b,1),(a,2),(b,2),(a,3),(b,3)


然而,在使用groupByKey的时候,所有的key-value对都被shuffle了。导致了大量不必要的网络传输。

要决定一个数据对被shuffle到哪台机器上,Spark会在数据对的key上调用分区函数。当shuffle后的数据在内存中放不下的时候,Spark会将其spill到硬盘上。然而,它每次把一个key的所有数据存到硬盘,所以如果某一个key的所有键值对在内存中存不下了,就会产生OOM异常。

groupByKey的工作过程如下:

GroupByKey

而上面的groupByKey的过程中,shuffle传输的数据是rdd中所有的元素,因此性能很差。

可以想象当对于大数据集,两个方法之间的性能差异会有多么夸张。


另外两个优于groupByKey的函数:

combineByKey:can be used when you are combining elements but your return type differs from your input value type.

foldByKey:merges the values for each key using an associative function and a neutral "zero value".

这两个函数的具体用法可以查看另一篇文章:

《Spark算子:RDD键值转换操作(2)–combineByKey、foldByKey》http://blog.csdn.net/sdujava2011/article/details/50598481


内容整理自https://databricks.gitbooks.io/databricks-spark-knowledge-base/content/best_practices/prefer_reducebykey_over_groupbykey.html,所有权力归原作者所有。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值