spark transform系列__groupByKey
这个操作的作用依据同样的key的全部的value存储到一个集合中的一个玩意.
def groupByKey(): RDD[(K, Iterable[V])] = self.withScope {
groupByKey(defaultPartitioner(self))
}
在做groupByKey的操作时,由于须要依据key对数据进行又一次的分区操作,因此这个操作须要有一个partitioner的实例.默认是hash算子.这个操作依据当前操作的RDD中是否有partitioner,同一时候这个partitioner与当前的传入的partitioner的实例是否同样来推断是否须要运行shuffle操作.
假设是默认的hashPartitioner时,检查spark.default.parallelism配置是否有配置,假设有分区个数按这个配置来设置,否则使用当前进行此groupByKey操作的rdd的partitions来设置.
def groupByKey(partitioner: Partitioner): RDD[(K, Iterable[V])]
= self.withScope {
这里同样与reduceByKey的操作一样,通过调用combineByKeyWithClassTag的函数来进行处理,
不同的是,withClassTag的合并操作是一个CompactBuffer[V]类型.
这里生成aggregator实例须要的三个函数时,
createCombiner:假设key眼下还有值时,依据当前传入的key-value中的value生成一个CompactBuffer的实例,并存储到key相应的位置,
mergeValue:传入一个key-value时,假设key相应的CompactBuffer已经存在,把这个value加入到这个buffer中.
mergeCombiners:这个主要在shuffle结束时,把key同样的多个buffer进行合并.
须要注意的是,在运行groupByKey的操作时,会把mapSideCombine设置为false,表示不运行map端的聚合.
为什么groupByKey不做mapSideCombine的操作呢,由于在groupByKey的操作中,会先依据同样的key,把value存储到一个buffer中,这个地方并不会设计到map端combine的操作会降低多少的网络传输的开效,假设做map combine操作时,反而添加了map端writer的内存使用.
// groupByKey shouldn't use map side combine because map side combine does not
// reduce the amount of data shuffled and requires all map side data be inserted
// into a hash table, leading to more objects in the old gen.
val createCombiner = (v: V) => CompactBuffer(v)
val mergeValue = (buf: CompactBuffer[V], v: V) => buf += v
val mergeCombiners = (c1: CompactBuffer[V], c2: CompactBuffer[V]) => c1 ++= c2
val bufs = combineByKeyWithClassTag[CompactBuffer[V]](
createCombiner, mergeValue, mergeCombiners, partitioner, mapSideCombine = false)
bufs.asInstanceOf[RDD[(K, Iterable[V])]]
}
在combineByKeyWithClassTag的操作函数中的处理:
mapSideCombine的传入參数为false.
这个地方,依据上面的三个函数,生成Aggregator,这里的K,V,C分别代表key的类型,value的类型,C在groupByKey的操作中是一个CompactBuffer[V]的类型
val aggregator = new Aggregator[K, V, C](
self.context.clean(createCombiner),
self.context.clean(mergeValue),
self.context.clean(mergeCombiners))
这里主要是看看当前的partitioner是否与当前运行这个操作的rdd的partitioner实例同样.同样就不在须要运行shuffle操作,否则就须要运行shuffle操作,生成新的ShuffledRDD实例.
if (self.partitioner == Some(partitioner)) {
self.mapPartitions(iter => {
val context = TaskContext.get()
new InterruptibleIterator(context, aggregator.combineValuesByKey(iter,
context))
}, preservesPartitioning = true)
} else {
new ShuffledRDD[K, V, C](self, partitioner)
.setSerializer(serializer)
.setAggregator(aggregator)
.setMapSideCombine(mapSideCombine)
}
在Aggregator的操作中,假设mapSideCombine的參数为false时,通过Aggregator中的combineValuesByKey函数运行数据的合并操作.假设mapSideCombine的參数为true时,通过Aggregator中的combineCombinersByKey函数运行数据的合并操作(仅仅运行第三个函数,由于map端已经把结果合并成了C的类型).
在Aggregator的合并操作中,通过ExternalAppendOnlyMap实例来进行数据的合并(insertAll).这个实例会最大可能的使用内存,假设内存实在不够用时,考虑对内存中的数据进行spill到磁盘的操作.
spark transform系列__groupByKey的更多相关文章
- spark transform系列__sortByKey
该函数主要功能:通过指定的排序规则与进行排序操作的分区个数,对当前的RDD中的数据集按KEY进行排序,并生成一个SHUFFLEdrdd的实例,这个过程会运行shuffle操作,在运行排序操作前,sor ...
- Spark JDBC系列--取数的四种方式
Spark JDBC系列--取数的四种方式 一.单分区模式 二.指定Long型column字段的分区模式 三.高自由度的分区模式 四.自定义option参数模式 五.JDBC To Other Dat ...
- rxjs5.X系列 —— transform系列 api 笔记
欢迎指导与讨论:) 前言 本文是笔者翻译 RxJS 5.X 官网各类operation操作系列的的第一篇 -- transform转换.如有错漏,希望大家指出提醒O(∩_∩)O.更详细的资料尽在rxj ...
- spark学习系列
转自: http://www.cnblogs.com/magj2006/p/4316264.html spark 系列文章汇总 源码导读 spark 源码导读1 从spark启动脚本开始 spark ...
- (转)Spark 算子系列文章
http://lxw1234.com/archives/2015/07/363.htm Spark算子:RDD基本转换操作(1)–map.flagMap.distinct Spark算子:RDD创建操 ...
- spark transform操作卡死,请先对rdd进行action操作
这两天一直在写spark程序,遇到了一个奇怪的问题. 问题简单描述如下,有两个RDD,设为rdd_a,rdd_b,当将这两个rdd合并的时候,spark会在运行中卡死. 解决方式也是奇葩. 只要在合并 ...
- Spark机器学习系列之13: 支持向量机SVM
Spark 优缺点分析 以下翻译自Scikit. The advantages of support vector machines are: (1)Effective in high dimensi ...
- Spark 概念学习系列之从物理执行的角度透视spark Job(十七)
本博文主要内容: 1.再次思考pipeline 2.窄依赖物理执行内幕 3.宽依赖物理执行内幕 4.Job提交流程 一:再次思考pipeline 即使采用pipeline的方式,函数f对依赖的RDD ...
- Spark 概念学习系列之从spark架构中透视job(十六)
本博文的主要内容如下: 1.通过案例观察Spark架构 2.手动绘制Spark内部架构 3.Spark Job的逻辑视图解析 4.Spark Job的物理视图解析 1.通过案例观察Spark架构 s ...
随机推荐
- fastdfs+nginx的安装部署
原理图: fastdfs适用场景: fastdfs特别适合海量 中小文件(建议范围:4KB< file_size <500MB)为载体的在线服务. 安装系统介绍: CentOS6.6 安装 ...
- Javascript平稳退化、渐进增强
平稳退化 : javascript平稳退化就是如果一个浏览器完全不支持js或者禁用js的时候,它的基本功能不会受到任何影响.比方说一个网站使用了大量javascript来优化页面,我们现在把浏览器的j ...
- ZBrush实用插件ZAppLink简介
ZAppLink是ZBrush版本推出时被评为最值得期待的插件.事实证明,ZAppLink的出现让工具与工具之间有了交流,搭起软件与软件的沟通桥梁. ZAppLink插件专用于扩展ZBrush®的绘制 ...
- Python 曲线拟合
#曲线拟合 fig = plt.figure() ax = fig.add_subplot(111)#将画布分割成1行1列,图像画在从左到右从上到下的第1块 ax.plot(Num,a,label=u ...
- BZOJ2225: [Spoj 2371]Another Longest Increasing CDQ分治,3维LIS
Code: #include <cstdio> #include <algorithm> #include <cstring> #define maxn 20000 ...
- vue项目input的placeholder根据用户的选择改变
html部分 <el-input :placeholder="holder" v-model="searchKey"> <el-select ...
- 养活一款APP要“烧”多少钱?
Duang!又一款APP刷爆朋友圈.大片范儿的电影截图.意味深长的经典对白均出自一款名为“足记”的APP. 足记团队刚于去年8月完成天使期融资,投资方是光速创投和紫辉创投,目前正准备A轮融资.且近一周 ...
- Java读书笔记一(异常处理)
1.介绍 在开发过程中.都会遇到程序执行时的异常,比如逻辑错误.硬件故障等,本篇博客将会具体的介绍一下Java中的异常处理机制. 2.Try和Catch捕获异常 我们在处理异常过程中经经常使用到的就是 ...
- 【Android进阶篇】Fragment的两种载入方式
一.概述 Fragment(碎片,片段)是在Android 3.0后才引入的,基本的目的是为了实如今大屏幕设备上的更加动态更加灵活的UI设计. 这是由于平板电脑的屏幕比手机大得多,所以屏幕上能够放很多 ...
- linux安装oracleclient
1.准备好所须要的安装包,http://www.oracle.com/technetwork/database/features/instant-client/index-097480.html这个网 ...