Spark的CombineByKey
combineBykey关键是要明白里面的三个函数:
1. 当某个key第一次出现的时候,走的是第一个函数(createCombin);A function that creates a combiner. In the aggregateByKey function the first argument was simply an initial zero value. In combineByKey we provide a function that will accept our current value as a parameter and return our new value that will be merged with addtional values.
2. 当某个keyN次出现(N > 1)的时候,将会走第二个函数;The second function is a merging function that takes a value and merges/combines it into the previously collecte value(s).
3. 第三个函数是发生shuffle的时候,数据汇总的处理;处理逻辑一般和第二个函数一致;两个参数是来自于两个区的待累计处理参数。The third function combines the merged values together. Basically this function takes the new values produced at the partition level and combines them until we end up with one singular value.
突然来看这个combineByKey有些唐突,不过你要明白combine含义就是合并,可能会好理解.combinebyKey很多时候会和map做接续,combine数据后,在map对于数据进行二次处理,比如下面的例子里面的求平均值;combineByKey做得是累加,当需要对累加值做后续处理的时候,map就出场了;另外,combinByKey其实可以写成mapValues+reduceByKey;mapValues + reduceByKey是两轮便利,combineByKey其实是一轮便利(不算第三个函数)。但是两者只是类似,却不相同;
1.mapValues: 当一个遍历每个元素的时候,处理,参数是当前待处理元素;
2.reduceByKey,是遍历一遍之后,第二遍遍历处理,一般是做累计逻辑处理,第一个参数就是历史累计值,第二个参数是当前待处理元素;
代码如下:
object Main {
def main(args: Array[String]) {
val scores = List(
ScoreDetail("xiaoming", "Math", 98),
ScoreDetail("xiaoming", "English", 88),
ScoreDetail("wangwu", "Math", 75),
ScoreDetail("wangwu", "English", 78),
ScoreDetail("lihua", "Math", 90),
ScoreDetail("lihua", "English", 80),
ScoreDetail("zhangsan", "Math", 91),
ScoreDetail("zhangsan", "English", 80))
var sparkConf = new SparkConf
//sparkConf.setMaster("yarn-client")
sparkConf.setAppName("app")
var sc = new SparkContext(sparkConf)
//val scoresWithKey = for( i<-scores) yield (i.studentName, i)
val scoresWithKey = scores.map(score => (score.studentName, score))
var scoresWithKeyRDD = sc.parallelize(scoresWithKey).partitionBy(new HashPartitioner(3)).cache
scoresWithKeyRDD.foreachPartition(partition => {
//println("***** partion.length: " + partition.size + "************")
while (partition.hasNext) {
val score = partition.next();
println("name: " + score._1 + "; id: " + score._2.score)
}
})
val avg = scoresWithKeyRDD.combineByKey(
(x: ScoreDetail) => {
println("score:" + x.score + "name: " + x.studentName)
(x.score, 1)},
(acc: (Float, Int), x: ScoreDetail) =>{
println("second ground:" + x.score + "name: " + x.studentName)
(acc._1 + x.score, acc._2 + 1)
},
(acc1: (Float, Int), acc2: (Float, Int)) => (acc1._1 + acc2._1, acc1._2 + acc2._2)
).map({ case (key, value) => (key, value._1 / value._2) })
/*
val avg = scoresWithKeyRDD.mapValues(value => (value.score, 1))
.reduceByKey((acc, item) => (acc._1 + item._1, acc._2 + item._2))
//.map(item => (item, item._2._1 / item._2._2)
.map({ case (key, value) => (key, value._1 / value._2) })
*/
avg.collect.foreach(println)
scoresWithKeyRDD.unpersist(true)
}
}
combineByKey的处理逻辑通过日志可以看到:
score:.0name: xiaoming
second ground:.0name: xiaoming
score:.0name: lihua
second ground:.0name: lihua
score:.0name: zhangsan
second ground:.0name: zhangsan
每个key只是走一次第一个函数;当同一个key第n次出现(n > 1)的时候,将会走第二个函数;这个和mapValues将会过遍历一遍,keyByValues再过一遍的逻辑还是不同的。
combineByKey的一个老对手是groupbyKey,这个说法其实不准确,reduceByKey才是groupByKey的老对手;因为无论是reduceByKey还是groupByKey,其实底层都是调用combinByKey;但是groupByKey将会导致大量的shuffle,因为groupByKey的实现逻辑是将各个分区的数据原封不动的shuffle到reduce机器,由reduce机器进行合并处理,见下图:

reduceByKey则是先将各个分区的数据进行合并(计算)处理后在shuffle到reducer机器;这样严重的减轻了数据传输的量。

Spark的CombineByKey的更多相关文章
- Spark入门(六)--Spark的combineByKey、sortBykey
spark的combineByKey combineByKey的特点 combineByKey的强大之处,在于提供了三个函数操作来操作一个函数.第一个函数,是对元数据处理,从而获得一个键值对.第二个函 ...
- Spark 的combineByKey函数
在Spark中有许多聚类操作是基于combineByKey的,例如group那个家族的操作等.所以combineByKey这个函数也是比较重要,所以下午花了点时间看来下这个函数.也参考了http:// ...
- Spark RDD——combineByKey
为什么单独讲解combineByKey? 因为combineByKey是Spark中一个比较核心的高级函数,其他一些高阶键值对函数底层都是用它实现的.诸如 groupByKey,reduceByKey ...
- spark之combineByKey
combineByKey def combineByKey[C](createCombiner: (V) => C, mergeValue: (C, V) => C, mergeCombi ...
- Spark实战系列目录
1 Spark rdd -- action函数详解与实战 2 Spark rdd -- transformations函数详解与实战(上) 3 Spark rdd -- transformations ...
- Spark入门(七)--Spark的intersection、subtract、union和distinc
Spark的intersection intersection顾名思义,他是指交叉的.当两个RDD进行intersection后,将保留两者共有的.因此对于RDD1.intersection(RDD2 ...
- Job 逻辑执行图
General logical plan 典型的 Job 逻辑执行图如上所示,经过下面四个步骤可以得到最终执行结果: 从数据源(可以是本地 file,内存数据结构, HDFS,HBase 等)读取数据 ...
- Spark API 之 combineByKey(一)
1 前言 combineByKey是使用Spark无法避免的一个方法,总会在有意或无意,直接或间接的调用到它.从它的字面上就可以知道,它有聚合的作用,对于这点不想做过多的解释,原因很简单, ...
- spark算子:combineByKey
假设我们有一组个人信息,我们针对人的性别进行分组统计,并进行统计每个分组中的记录数. scala> val people = List(("male", "Mobi ...
随机推荐
- UVA-10537 The Toll! Revisited (dijkstra)
题目大意:每经过一个地方就要交出相应的货物作为过路费,问将一批货物从起点运到终点,最少需要携带多少货物? 题目分析:在每一站交的过路费由当前拥有的货物量来决定,所以,要以终点为源点,求一次单源最短路即 ...
- [Java基础] 深入jar包:从jar包中读取资源文件
转载: http://hxraid.iteye.com/blog/483115?page=3#comments 我们常常在代码中读取一些资源文件(比如图片,音乐,文本等等).在单独运行的时候这些简单的 ...
- How to create Oracle ASM devices using device-mapper multipath devices in Red Hat Enterprise Linux 6
How to create Oracle ASM devices using device-mapper multipath devices in Red Hat Enterprise Linux 6 ...
- Kubernetes 1.5.3 部署
> kubernetes 1.5.3, 配置文档 # 1 初始化环境 ## 1.1 环境: | 节 点 | I P ||--------|-------------||no ...
- HTML5音视频播放(Video,Audio)和常见的坑处理
1. 前言背景 在HTML5出现之前,Web页面访问音视频主要是通过Flash,Activex插件,还有微软后来推出的silverlight来展现的,尽管FLASH曾经风靡全球,但是随着互联网的不断发 ...
- iOS中几种数据持久化方案
概论 所谓的持久化,就是将数据保存到硬盘中,使得在应用程序或机器重启后可以继续访问之前保存的数据.在iOS开发中,有很多数据持久化的方案,接下来我将尝试着介绍一下5种方案: plist文件(属性列表) ...
- L160
In the Soviet Union several cases have been reported recently of people whocan read and detect colou ...
- 【跟着stackoverflow学Pandas】How to iterate over rows in a DataFrame in Pandas-DataFrame按行迭代
最近做一个系列博客,跟着stackoverflow学Pandas. 以 pandas作为关键词,在stackoverflow中进行搜索,随后安照 votes 数目进行排序: https://stack ...
- 【跟着stackoverflow学Pandas】“Large data” work flows using pandas-pandas大数据处理流程
最近做一个系列博客,跟着stackoverflow学Pandas. 以 pandas作为关键词,在stackoverflow中进行搜索,随后安照 votes 数目进行排序: https://stack ...
- Java多线程编程实战指南(核心篇)读书笔记(三)
(尊重劳动成果,转载请注明出处:http://blog.csdn.net/qq_25827845/article/details/76686044冷血之心的博客) 博主准备恶补一番Java高并发编程相 ...