Spark中的CombineKey()详解
CombineKey()是最常用的基于键进行聚合的函数,大多数基于键聚合的函数都是用它实现的。和aggregate()一样,CombineKey()可以让用户返回与输入数据的类型不同的返回值。要理解CombineKey()需要先理解它在数据处理时是如何处理每个元素的。由于CombineKey()会遍历分区中的所有元素,因此每个元素的键要么还没有遇到,要么就是和之前的额某个元素的键相同。
如果遇到的是一个新元素,CombineKey()会使用一个叫做createCombiner()的函数来创建那个键对应的累加器的初始值,需要注意的是,这一过程会在每个分区中第一次出现各个键时发生,而不是在整个RDD中第一次出现时发生。
如果这是一个在处理当前分区之前已经遇到的键,它会使用mergeValue()方法将该键的累加器对应的值与这个新的值进行合并。
由于每个分区都是独立处理的,因此对于同一个键可以有多个累加器。如果有两个或者更多的分区都有对应同一个键的累加器,就需要使用用户提供的mergeCombiners()方法将各个分区的结果进行合并。
如果已知数据在进行combineByKey() 时无法从map 端聚合中获益的话,可以禁用它。例如,由于聚合函数(追加到一个队列)无法在map 端聚合时节约任何空间,groupByKey() 就把它禁用了。如果希望禁用map 端组合,就需要指定分区方式。就目前而言,你可以通过传递rdd.partitioner 来直接使用源RDD 的分区方式。
combineByKey() 有多个参数分别对应聚合操作的各个阶段,因而非常适合用来解释聚合操作各个阶段的功划分。为了更好地演示combineByKey() 是如何工作的,下面来看看如何计算各键对应的平均值:
在Python 中使用combineByKey() 求每个键对应的平均值
sumCount = nums.combineByKey((lambda x: (x,1)),
(lambda x, y: (x[0] + y, x[1] + 1)),
(lambda x, y: (x[0] + y[0], x[1] + y[1])))
sumCount.map(lambda key, xy: (key, xy[0]/xy[1])).collectAsMap()
在Scala 中使用combineByKey() 求每个键对应的平均值
val result = input.combineByKey(
(v) => (v, 1),
(acc: (Int, Int), v) => (acc._1 + v, acc._2 + 1),
(acc1: (Int, Int), acc2: (Int, Int)) => (acc1._1 + acc2._1, acc1._2 + acc2._2)
).map{ case (key, value) => (key, value._1 / value._2.toFloat) }
result.collectAsMap().map(println(_))
在Java 中使用combineByKey() 求每个键对应的平均值
public static class AvgCount implements Serializable {
public AvgCount(int total, int num) { total_ = total; num_ = num; }
public int total_;
public int num_;
public float avg() { returntotal_/(float)num_; }
}
Function<Integer, AvgCount> createAcc = new Function<Integer, AvgCount>() {
public AvgCount call(Integer x) {
return new AvgCount(x, 1);
}
};
Function2<AvgCount, Integer, AvgCount> addAndCount =
new Function2<AvgCount, Integer, AvgCount>() {
public AvgCount call(AvgCount a, Integer x) {
a.total_ += x;
a.num_ += 1;
return a;
}
};
Function2<AvgCount, AvgCount, AvgCount> combine =
new Function2<AvgCount, AvgCount, AvgCount>() {
public AvgCount call(AvgCount a, AvgCount b) {
a.total_ += b.total_;
a.num_ += b.num_;
return a;
}
};
AvgCount initial = new AvgCount(0,0);
JavaPairRDD<String, AvgCount> avgCounts =
nums.combineByKey(createAcc, addAndCount, combine);
Map<String, AvgCount> countMap = avgCounts.collectAsMap();
for (Entry<String, AvgCount> entry : countMap.entrySet()) {
System.out.println(entry.getKey() + ":" + entry.getValue().avg());
}
combineByKey() 数据流示意图
有很多函数可以进行基于键的数据合并。它们中的大多数都是在combineByKey() 的基础上实现的,为用户提供了更简单的接口。不管怎样,在Spark 中使用这些专用的聚合函数,始终要比手动将数据分组再归约快很多。
Spark中的CombineKey()详解的更多相关文章
- Spark中的分区方法详解
转自:https://blog.csdn.net/dmy1115143060/article/details/82620715 一.Spark数据分区方式简要 在Spark中,RDD(Resilien ...
- [Spark内核] 第36课:TaskScheduler内幕天机解密:Spark shell案例运行日志详解、TaskScheduler和SchedulerBackend、FIFO与FAIR、Task运行时本地性算法详解等
本課主題 通过 Spark-shell 窥探程序运行时的状况 TaskScheduler 与 SchedulerBackend 之间的关系 FIFO 与 FAIR 两种调度模式彻底解密 Task 数据 ...
- Spark log4j日志配置详解(转载)
一.spark job日志介绍 spark中提供了log4j的方式记录日志.可以在$SPARK_HOME/conf/下,将 log4j.properties.template 文件copy为 l ...
- php中关于引用(&)详解
php中关于引用(&)详解 php的引用(就是在变量或者函数.对象等前面加上&符号) 在PHP 中引用的意思是:不同的变量名访问同一个变量内容. 与C语言中的指针是有差别的.C语言中的 ...
- JavaScript正则表达式详解(二)JavaScript中正则表达式函数详解
二.JavaScript中正则表达式函数详解(exec, test, match, replace, search, split) 1.使用正则表达式的方法去匹配查找字符串 1.1. exec方法详解 ...
- AngularJS select中ngOptions用法详解
AngularJS select中ngOptions用法详解 一.用法 ngOption针对不同类型的数据源有不同的用法,主要体现在数组和对象上. 数组: label for value in a ...
- 【转载】C/C++中extern关键字详解
1 基本解释:extern可以置于变量或者函数前,以标示变量或者函数的定义在别的文件中,提示编译器遇到此变量和函数时在其他模块中寻找其定义.此外extern也可用来进行链接指定. 也就是说extern ...
- oracle中imp命令详解 .
转自http://www.cnblogs.com/songdavid/articles/2435439.html oracle中imp命令详解 Oracle的导入实用程序(Import utility ...
- Android中Service(服务)详解
http://blog.csdn.net/ryantang03/article/details/7770939 Android中Service(服务)详解 标签: serviceandroidappl ...
随机推荐
- idou教你学Istio10 : 如何用Istio实现K8S Egress流量管理
上一篇我们了解了如何控制入口流量,本文主要介绍在使用Istio时如何访问集群外服务,即对出口流量的管理. 默认安装的Istio是不能直接对集群外部服务进行访问的,如果需要将外部服务暴露给 Istio ...
- 当前form窗体随系统屏幕变化
private void 新建_Load(object sender, EventArgs e) { int DeskWidth = Screen.PrimaryScreen.WorkingArea. ...
- 用Python做一个飞机大战游戏
基于pygame的一款小游戏 这是我上半年做的一款小游戏,但是一直忘记了,现在才上传代码. github项目地址:StarMan 代码基于pygame,Python版本3.5.2运行正常. 游戏很简单 ...
- less混合
混合(mixin)变量 .border{ border: 5px solid pink; } .box{ width: 300px;height:300px; .border; } => .bo ...
- 从项目开始的Java开发学习
积累了一些项目中见到的代码,希望见一次之后自己也能写出来. 一.通过cxf JaxWsDynamicClientFactory进行WebService 客户端调用 代码:在项目中从非项目内的接口获取数 ...
- Http协议与TCP协议
背景 在日常工作中,经常会遇到某某框架是基于Http协议或者TCP协议,今天,就针对于该协议,整理下 从本质上来说,Http协议与TCP协议是应用在不同网络层,Http协议处于应用层,TCP处于传输层 ...
- [Google Guava] 10-散列
原文链接 译文链接 译者:沈义扬 概述 Java内建的散列码[hash code]概念被限制为32位,并且没有分离散列算法和它们所作用的数据,因此很难用备选算法进行替换.此外,使用Java内建方法实现 ...
- 一个项目中:只能存在一个 WebMvcConfigurationSupport (添加swagger坑)
问题再现: 1.添加了swagger配置,导致接口响应的中文乱码 2.于是又添加了配置解决中文乱码的配置: 问题来了,添加了CharsetConfig 配置后swagger的配置失效了,访问404,搞 ...
- 【概率论】3-8:随机变量函数(Functions of a Random Variable)
title: [概率论]3-8:随机变量函数(Functions of a Random Variable) categories: Mathematic Probability keywords: ...
- devstack cinder-volume服务状态为down
cinder-manage service list 查看到有一个 xxx状态 Binary Host Zone Status State Updated At RPC Version Object ...