您的位置:首页 > 其它

在Spark中尽量少使用GroupByKey函数

2015-06-11 18:26 447 查看
为什么建议尽量在Spark中少用GroupByKey,让我们看一下使用两种不同的方式去计算单词的个数,第一种方式使用
reduceByKey
;另外一种方式使用
groupByKey
,代码如下:

01
#
User
:
过往记忆
02
#
Date
:
2015
-
05
-
18
03
#
Time
:
下午
22
:
26
04
#
bolg
:
http
:
//www.iteblog.com
05
#
本文地址:http
:
//www.iteblog.com/archives/1357
06
#
过往记忆博客,专注于hadoop、hive、spark、shark、flume的技术博客,大量的干货
07
#
过往记忆博客微信公共帐号:iteblog
_
hadoop
08
09
val
words
=
Array(
"one"
,
"two"
,
"two"
,
"three"
,
"three"
,
"three"
)
10
val
wordPairsRDD
=
sc.parallelize(words).map(word
=
>
(word,
1
))
11
12
val
wordCountsWithReduce
=
wordPairsRDD
13
.reduceByKey(
_
+
_
)
14
.collect()
15
16
val
wordCountsWithGroup
=
wordPairsRDD
17
.groupByKey()
18
.map(t
=
>
 (t.
_
1
,
 t.
_
2
.sum))
19
.collect()
  虽然两个函数都能得出正确的结果, 但
reduceByKey
函数更适合使用在大数据集上。
这是因为Spark知道它可以在每个分区移动数据之前将输出数据与一个共用的 key 结合。

  借助下图可以理解在
reduceByKey
里发生了什么。
注意在数据对被搬移前同一机器上同样的 key 是怎样被组合的(
reduceByKey
中的
lamdba 函数)。然后 lamdba 函数在每个区上被再次调用来将所有值 reduce成一个最终结果。整个过程如下:









如果想及时了解Spark、Hadoop或者Hbase相关的文章,欢迎关注微信公共帐号:iteblog_hadoop

  另一方面,当调用
groupByKey
时,所有的键值对(key-value
pair) 都会被移动。在网络上传输这些数据非常没有必要。避免使用
GroupByKey


  为了确定将数据对移到哪个主机,Spark会对数据对的 key 调用一个分区算法。 当移动的数据量大于单台执行机器内存总量时 Spark 会把数据保存到磁盘上。 不过在保存时每次会处理一个 key 的数据,所以当单个 key 的键值对超过内存容量会存在内存溢出的异常。 这将会在之后发行的 Spark 版本中更加优雅地处理,这样的工作还可以继续完善。 尽管如此,仍应避免将数据保存到磁盘上,这会严重影响性能。





如果想及时了解Spark、Hadoop或者Hbase相关的文章,欢迎关注微信公共帐号:iteblog_hadoop

  你可以想象一个非常大的数据集,在使用 reduceByKey和 groupByKey 时他们的差别会被放大更多倍。以下函数应该优先于 groupByKey :

  (1)、
combineByKey
组合数据,但是组合之后的数据类型与输入时值的类型不一样。

  (2)、
foldByKey
合并每一个
key 的所有值,在级联函数和“零值”中使用。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: