1.reduceByKey(func)

功能:

  使用 func 函数合并具有相同键的值。

示例:

val list = List("hadoop","spark","hive","spark")
val rdd = sc.parallelize(list)
val pairRdd = rdd.map((_,1))
pairRdd.reduceByKey(_+_).collect.foreach(println)

上例中,我们先是建立了一个list,然后建立通过这个list集合建立一个rdd

然后我们通过map函数将list的rdd转化成键值对形式的rdd

然后我们通过reduceByKey方法对具有相同key的值进行func(_+_)的累加操作。

输入结果如下

(hive,1)
(spark,2)
(hadoop,1)
list: List[String] = List(hadoop, spark, hive, spark)
rdd: org.apache.spark.rdd.RDD[String] = ParallelCollectionRDD[127] at parallelize at command-3434610298353610:2
pairRdd: org.apache.spark.rdd.RDD[(String, Int)] = MapPartitionsRDD[128] at map at command-3434610298353610:3 
pairRdd.collect.foreach(println) //打印pairRdd
(hive,1)
(spark,1)
(hadoop,1)
(spark,1)

我们需要留意的事情是,我们调用了reduceByKey操作的返回的结果类型是

org.apache.spark.rdd.RDD[(String, Int)]  

注意,我们这里的collect()方法的作用是收集分布在各个worker的数据到driver节点。

如果不使用这个方法,每个worker的数据只在自己本地显示,并不会在driver节点显示。

2.groupByKey()

功能:

  对具有相同key的value进行分组。

示例:

val list = List("hadoop","spark","hive","spark")
val rdd = sc.parallelize(list)
val pairRdd = rdd.map(x => (x,1))
pairRdd.groupByKey().collect.foreach(println)

我们同样是对跟上面同样的pairRdd进行groupByKey()操作

得出的结果为

(hive,CompactBuffer(1))
(spark,CompactBuffer(1, 1))
(hadoop,CompactBuffer(1))
list: List[String] = List(hadoop, spark, hive, spark)
rdd: org.apache.spark.rdd.RDD[String] = ParallelCollectionRDD[130] at parallelize at command-3434610298353610:2
pairRdd: org.apache.spark.rdd.RDD[(String, Int)] = MapPartitionsRDD[131] at map at command-3434610298353610:3

可以看到,结果并不是把具有相同key值进行相加,而是就简单的进行了分组,生成一个sequence。

其实,我们可以把groupByKey()当作reduceByKey(func)操作的一部分,

reduceByKey(func)先是对rdd进行groupByKey()然后在对每个分组进行func操作。

pairRdd.reduceByKey(_+_).collect.foreach(println)
等同于
pairRdd.groupByKey().map(t => (t._1,t._2.sum)).collect.foreach(println)

我们这里通过groupByKey()后调用map遍历每个分组,然后通过t => (t._1,t._2.sum)对每个分组的值进行累加。

因为groupByKey()操作是把具有相同类型的key收集到一起聚合成一个集合,集合中有个sum方法,对所有元素进行求和。

注意,(k,v)形式的数据,我们可以通过 ._1,._2 来访问键和值,

用占位符表示就是 _._1,_._2,这里前面的两个下划线的含义是不同的,前边下划线是占位符,后边的是访问方式。 

我们记不记得 ._1,._2,._3 是元组的访问方式。我们可以把键值看成二维的元组。

3.reduceByKey(func)和groupByKey()的区别

reduceByKey()对于每个key对应的多个value进行了merge操作,最重要的是它能够先在本地进行merge操作。merge可以通过func自定义。

groupByKey()也是对每个key对应的多个value进行操作,但是只是汇总生成一个sequence,本身不能自定义函数,只能通过额外通过map(func)来实现。

使用reduceByKey()的时候,本地的数据先进行merge然后再传输到不同节点再进行merge,最终得到最终结果。

而使用groupByKey()的时候,并不进行本地的merge,全部数据传出,得到全部数据后才会进行聚合成一个sequence,

groupByKey()传输速度明显慢于reduceByKey()。

虽然groupByKey().map(func)也能实现reduceByKey(func)功能,但是,优先使用reduceByKey(func)

【spark】常用转换操作:reduceByKey和groupByKey的更多相关文章

  1. 【Spark算子】:reduceByKey、groupByKey和combineByKey

    在spark中,reduceByKey.groupByKey和combineByKey这三种算子用的较多,结合使用过程中的体会简单总结: 我的代码实践:https://github.com/wwcom ...

  2. 【spark】常用转换操作:join

    join就表示内连接. 对于内链接,对于给定的两个输入数据集(k,v1)和(k,v2) 根据相同的k进行连接,最终得到(k,(v1,v2))的数据集. 示例 val arr1 = Array((&qu ...

  3. 【spark】常用转换操作:keys 、values和mapValues

    1.keys 功能: 返回所有键值对的key 示例 val list = List("hadoop","spark","hive",&quo ...

  4. 【spark】常用转换操作:sortByKey()和sortBy()

    1.sortByKey() 功能: 返回一个根据键排序的RDD 示例 val list = List(("a",3),("b",2),("c" ...

  5. java实现spark常用算子之ReduceByKey

    import org.apache.spark.SparkConf;import org.apache.spark.api.java.JavaPairRDD;import org.apache.spa ...

  6. Spark常用RDD操作总结

    aggregate 函数原型:aggregate(zeroValue, seqOp, combOp) seqOp相当于Map combOp相当于Reduce zeroValue是seqOp每一个par ...

  7. iOS中NSDate常用转换操作整合

    //当前时间格式化, 例:YYYY-MM-dd-EEEE-HH:mm:ss + (NSString *)getCurrentDataWithDateFormate:(NSString *)format ...

  8. 【spark】RDD操作

    RDD操作分为转换操作和行动操作. 对于RDD而言,每一次的转化操作都会产生不同的RDD,供一个操作使用. 我们每次转换得到的RDD是惰性求值的 也就是说,整个转换过程并不是会真正的去计算,而是只记录 ...

  9. Spark常用函数讲解之键值RDD转换

    摘要: RDD:弹性分布式数据集,是一种特殊集合 ‚ 支持多种来源 ‚ 有容错机制 ‚ 可以被缓存 ‚ 支持并行操作,一个RDD代表一个分区里的数据集RDD有两种操作算子:         Trans ...

随机推荐

  1. 4.Data Types in the mongo Shell-官方文档摘录

    总结: 1.MongoDB 的BSON格式支持额外的数据类型 2 Date 对象内部存储64位字节存整数,存储使用NumberLong()这个类来存,使用NumberInt()存32位整数,128位十 ...

  2. 序列化组件之生成hypermedialink

    一  生成hypermedialink(极少数) 组件 class BooksSerializer(serializers.ModelSerializer): name = serializers.C ...

  3. 批量处理任务进度条控制—基于BackgroundWorker

    今天要做一个批量处理图层数据的功能,希望在处理任务过程中,各个任务都能在进度条中显示自己的当前进度,决定继续使用强大易用的BackgroundWorker组件.通过在RunWorkerComplete ...

  4. Delphi 正则表达式语法(9): 临界匹配 - 也叫"预搜索"与"反向预搜索"

    Delphi 正则表达式语法(9): 临界匹配 - 也叫"预搜索"与"反向预搜索" //匹配右边 var   reg: TPerlRegEx; begin   ...

  5. Canvas:技术小结

    Canvas:技术小结 资料 [教程:MDN官方中文教程] https://developer.mozilla.org/zh-CN/docs/Web/API/Canvas_API/Tutorial [ ...

  6. vue-cli脚手架build目录中check-versions.js的配置

    转载自:https://www.cnblogs.com/ye-hcj/p/7074363.html 本文介绍vue-cli脚手架build目录中check-versions.js的配置 本文件是用来检 ...

  7. Word 中设置图、表、公式、代码要与正文之间行间距

    一.概述 在撰写论文等文档时,常常对图.表.公式.代码要与正文之间行间距有要求.例如: (5)图.表.公式.代码要与正文之间有6磅的行间距. 二.设置方式 选中 图/表/公式/代码 与 图题/表头/- ...

  8. json数据结构

    JSON即JavaScript Object Natation,它是一种轻量级的数据交换格式,非常适合服务器与JavaScript的交互.JSON易于人阅读和编写.同时也易于机器解析和生成.JSON采 ...

  9. Deep Learning(深度学习)学习系列

    目录: 一.概述 二.背景 三.人脑视觉机理 四.关于特征        4.1.特征表示的粒度        4.2.初级(浅层)特征表示        4.3.结构性特征表示        4.4 ...

  10. Django学习笔记之使用 Django项目开发框架

    Django 项目是一个定制框架,它源自一个在线新闻 Web 站点,于 2005 年以开源的形式被释放出来.Django 框架的核心组件有: 用于创建模型的对象关系映射 为最终用户设计的完美管理界面 ...