【译】避免使用GroupByKey

by:leotse

原文:Avoid GroupByKey

译文

让我们来看两个wordcount的例子,一个使用了reduceByKey,而另一个使用groupByKey:

1
2
3
4
5
6
7
8
9
10
11
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的例子表现更佳。这是因为在shuffle输出的数据前,Spark会Combine每一个partition上具有相同key的输出结果。

看下图我们就能理解reduceByKey的工作流程。我们注意到同一台机器上数据shuffle之前,相同key的数据(通过调用传入reduceByKey的lambda函数)Combine在一起的,然后再一次调用这个lambda函数去reduce来自各个partition的全部值,从而得到最终的结果。

另一方面,当调用groupByKey的时候,所有的键值对都会进行shuffle,这将增加很多无谓的数据进行网络传输。

为了确定哪台机器将接受Shuffle后的键值对,Spark会针对该键值对数据的key调用一个分区函数。当某一台executor机器上的内存不足以保存过多的Shuffle后数据时,Spark就会溢写数据到磁盘上。然而,这种溢写磁盘会一次性将一个key的全部键值对数据写入磁盘,因此如果一个key拥有过多键值对数据——多到内存放不下时,将会抛出Out Of Memory异常。在之后发布的Spark中将会更加优雅地处理这种情况,使得这个job仍会继续运行,但是我们仍然需要避免(使用groupByKey)。当Spark需要溢写磁盘的时候,它的性能将受到严重影响

如果你有一个非常大的数据集,那么reduceByKeygroupByKey进行shuffle的数据量之间的差异将会更加夸张。

下面是一些你可以用来替代groupByKey的函数:
1)当你在combine数据但是返回的数据类型因输入值的类型而异时,你可以使用combineByKey
2)如果key使用到结合函数和“零值”,你可以用foldByKey函数合并value;

spark中groupByKey与reducByKey的更多相关文章

  1. Spark 中 GroupByKey 相对于 combineByKey, reduceByKey, foldByKey 的优缺点

    避免使用GroupByKey 我们看一下两种计算word counts 的方法,一个使用reduceByKey,另一个使用 groupByKey: val words = Array("on ...

  2. Spark中groupByKey、reduceByKey与sortByKey

    groupByKey把相同的key的数据分组到一个集合序列当中: [("hello",1), ("world",1), ("hello",1 ...

  3. 在Spark中尽量少使用GroupByKey函数(转)

    原文链接:在Spark中尽量少使用GroupByKey函数 为什么建议尽量在Spark中少用GroupByKey,让我们看一下使用两种不同的方式去计算单词的个数,第一种方式使用reduceByKey  ...

  4. Spark中的编程模型

    1. Spark中的基本概念 Application:基于Spark的用户程序,包含了一个driver program和集群中多个executor. Driver Program:运行Applicat ...

  5. 关于Spark中RDD的设计的一些分析

    RDD, Resilient Distributed Dataset,弹性分布式数据集, 是Spark的核心概念. 对于RDD的原理性的知识,可以参阅Resilient Distributed Dat ...

  6. Spark中的键值对操作-scala

    1.PairRDD介绍     Spark为包含键值对类型的RDD提供了一些专有的操作.这些RDD被称为PairRDD.PairRDD提供了并行操作各个键或跨节点重新进行数据分组的操作接口.例如,Pa ...

  7. Spark中的键值对操作

    1.PairRDD介绍     Spark为包含键值对类型的RDD提供了一些专有的操作.这些RDD被称为PairRDD.PairRDD提供了并行操作各个键或跨节点重新进行数据分组的操作接口.例如,Pa ...

  8. 【Spark篇】--Spark中的宽窄依赖和Stage的划分

    一.前述 RDD之间有一系列的依赖关系,依赖关系又分为窄依赖和宽依赖. Spark中的Stage其实就是一组并行的任务,任务是一个个的task . 二.具体细节 窄依赖 父RDD和子RDD parti ...

  9. 020 Spark中分组后的TopN,以及Spark的优化(重点)

    一:准备 1.源数据 2.上传数据 二:TopN程序编码 1.程序 package com.ibeifeng.bigdata.spark.core import java.util.concurren ...

随机推荐

  1. Hexo搭建静态个人博客

    Hexo简介 之前在Github上托管的博客就是使用jekyll搭建的,官方的Github Pages同样推荐使用它.我之前体验了一下jekyll,没有达到我想要的效果.于是寻找替代方案,搜索同类博客 ...

  2. 归并排序的go语言与C++实现对比

    最近对go语言发生了兴趣,发现go语言语法简洁,非常适合算法的描述和实现,于是对归并排序进行了实现. 例子中需要排序的队列是长度为100的从100到1的数列,排序算法是正序排序,排序正确的话,结果应当 ...

  3. awk中{print $1}什么意思

    给你举个例子,echo "aa bb cc" | awk -F '{print $1}' 结果就是aa,意思是把字符串按空格分割,取第一个,自己做个测试就明白了!awk是用来提取列 ...

  4. arguments对象,caller 和 callee

    arguments对象是比较特别的一个对象,arguments非常类似Array,但实际上又不是一个Array实例. 它指的是函数对象里的参数,且只能在函数内部使用. 使用 检测函数的参数个数,引用属 ...

  5. Android:OpenFire 相关API (持续更新)

    基于XMPP协议的聊天服务器.最近会一直更新相关的API. 需要的软件:OpenFire(服务器),Spark(客户端--测试用),Asmack(Jar包) 1.连接服务器的代码 private vo ...

  6. Base64技术:把对象转变成字符串

    需求:在安卓移动端和服务器进行数据交互的时候,有些时候需要上传,下载文件.如果所有的参数都变成字符串,会更加方便. 原理:Base64只是把byte[]数组进行了编码,然后再解码的过程,文档内容无法直 ...

  7. 存储过程sql语句

    select count(virtualacc) into v_count  from T_ATMMONITOR WHERE virtualacc = v_number; 用于存储过程中,是把coun ...

  8. gridControl 部分属性

    DEVexpress GridControl 属性设置 2013年11月22日 ⁄ 综合 ⁄ 共 18319字 ⁄ 字号 小 中 大 ⁄ 评论关闭 1. 如何解决单击记录整行选中的问题 View-&g ...

  9. robotframework+seleniumlibrary自动化测试:测试环境搭建

    robotframework是由python编写的自动化测试框架,使用robotframework需要安装 python库 python 和 robotframework 的下载地址都可百度到 环境搭 ...

  10. DLL调试方法

    1.已经做好的dll不能设置:你可以用AfxMessageBox把信息打印出来.2.哪个地方调用的函数 把DLL重新编译一次 在把DLL放到工程里 从新添加一下 然后在你工程调用DLL内容的地方设置断 ...