【Spark 深入学习 07】RDD编程之旅基础篇03-键值对RDD
---------------------
本节内容:
· 键值对RDD出现背景
· 键值对RDD转化操作实例
· 键值对RDD行动操作实例
· 键值对RDD数据分区
· 参考资料
---------------------
虽然大部分Spark的RDD操作都支持所有种类的对象,但是有少部分特殊的操作只能作用于键值对类型的RDD。这类操作中最常见的就是分布的shuffle操作,比如将元素通过键来分组或聚集计算.因此,键值对RDD也是很多程序不可缺失的一部分.
一、键值对RDD出现背景
mapreduce框架是把数据转化为Key-value,再聚合为key-values的过程,在spark里key-value rdd(pair rdd)同样是最常用的,在每个应用中基本会用到,pair rdd里面的元素是Tuple2,pair rdd的transform函数很多.pari rdd是很多程序的构成要素,因为他们提供了并行性操作各个键或跨节点重新进行分组的操作接口.pair rdd最简单的2种创建方法:
(1)通过map创建实例所示:
---------------------
val line =sc.textFile("/tmp/test/core-site.xml");
val pairs=line.map(x=>(x.split(" ")(0),x));
pairs.foreach(println);
------
说明:
map:读取将读取的每一行用空格的第一行为key,整行内容为value
foreach:循环遍历打印出每个pair
---------------------
(2)直接读取键值对类型的数据
---------------------
val pairrdd = sc.parallelize(List((1,2),(3,4),(3,6)));
pairrdd.foreach(println);
------
说明:
parallelize:从外部数据集读取键值对数据
---------------------
二、键值对RDD转化操作实例
1.例子:reduceByKey/groupByKey/
---------------------
val pairrdd = sc.parallelize(List((1,2),(3,4),(3,6)));
val result=pairrdd.reduceByKey((x,y)=>x+y);
result.foreach(println);
------
说明:
reduceByKey:合并具有相同键的值
---------------------
val pairrdd = sc.parallelize(List((1,2),(3,4),(3,6)));
val result=pairrdd.groupByKey();
result.foreach(println);
------
说明:
groupByKey:将同一个key的值都放到一个列表中,通过ShuffledRDD将每个partition中fetch过来,shuffle机制默认用的是hashShuffle,spark1.1版本引入sorted shuffle,速度更快。shuffle操作后面接着mapPartition()操作,生成MapPartitionRDD.
2.例子:combineByKey/mapvalues
---------------------
val initialScores = Array(("Fred", 88.0), ("Fred", 95.0), ("Fred", 91.0), ("Wilma", 93.0), ("Wilma", 95.0), ("Wilma", 98.0));
val d1 = sc.parallelize(initialScores);
type MVType = (Int, Double) //定义一个元组类型(科目计数器,分数);
d1.combineByKey(
score => (1, score),
(c1: MVType, newScore) => (c1._1 + 1, c1._2 + newScore),
(c1: MVType, c2: MVType) => (c1._1 + c2._1, c1._2 + c2._2)
).map { case (name, (num, socre)) => (name, socre / num) }.collect().foreach(println);
------
说明:
combineByKey:
a .score => (1, score),我们把分数作为参数,并返回了附加的元组类型。 以"Fred"为列,当前其分数为88.0 =>(1,88.0) 1表示当前科目的计数器,此时只有一个科目
b.(c1: MVType, newScore) => (c1._1 + 1, c1._2 + newScore),注意这里的c1就是createCombiner初始化得到的(1,88.0)。在一个分区内,我们又碰到了"Fred"的一个新的分数91.0。当然我们要把之前的科目分数和当前的分数加起来即c1._2 + newScore,然后把科目计算器加1即c1._1 + 1
c.(c1: MVType, c2: MVType) => (c1._1 + c2._1, c1._2 + c2._2),注意"Fred"可能是个学霸,他选修的科目可能过多而分散在不同的分区中。所有的分区都进行mergeValue后,接下来就是对分区间进行合并了,分区间科目数和科目数相加分数和分数相加就得到了总分和总科目数
结果:
(Wilma,95.33333333333333)
(Fred,91.33333333333333)
---------------------
val pairrdd = sc.parallelize(List((1,2),(3,4),(3,6)));
val result=pairrdd.mapValues(x=>x+1);
result.foreach(println);
------
说明:
mapValues:对每个键的值应用一个函数而不改变键的内容
---------------------
3.例子:flatMapValues/keys/values/sotByKey
---------------------
val pairrdd = sc.parallelize(List((1,2),(3,4),(3,6)));
val result=pairrdd.flatMapValues(x=>(x to 5));
result.foreach(println);
------
说明:
flatMapValues:对每个值应用一个返回迭代器函数,然后对返回的每个值都生成一个对应原键的键值对记录,通常用于符号化.
结果:
(1,2)
(1,3)
(1,4)
(1,5)
(3,4)
(3,5)
---------------------
val pairrdd = sc.parallelize(List((1,2),(3,4),(3,6)));
val result=pairrdd.keys;//scala不要使用括号
result.foreach(println);
------
说明:
keys:对返回一个仅包含键的RDD.
---------------------
val pairrdd = sc.parallelize(List((1,2),(3,4),(3,6)));
val result=pairrdd.values;//scala不要使用括号
result.foreach(println);
------
说明:
values:对返回一个仅包含键的RDD.
---------------------
val pairrdd = sc.parallelize(List((1,2),(3,4),(3,6)));
val result=pairrdd.sortByKey(false);
result.foreach(println);
------
说明:
sortByKey:对返回一个根据键排序的RDD.默认不填为true,ascending升序方式
---------------------
4.例子:subtractByKey/join/leftOuterJoin/rightOuterJoin/coGroup
---------------------
val rdd= sc.parallelize(List((1,2),(3,4),(3,6)));
val other= sc.parallelize(List((3,6)));
val result=rdd.subtract(other);
result.foreach(println);
------
说明:删除rdd RDD 键与other RDD中的键相同的元素.
subtract:对返回一个根据键排序的RDD.
结果:
(3,4)
(1,2)
---------------------
val rdd= sc.parallelize(List((1,2),(3,4),(3,6)));
val other= sc.parallelize(List((3,9)));
val result=rdd.join(other);
result.foreach(println);
------
说明:
join:对2个RDD进行内连接,key相同的进行操作
结果:
(3,(4,9))
(3,(6,9))
---------------------
val rdd= sc.parallelize(List((1,2),(3,4),(3,6)));
val other= sc.parallelize(List((3,9)));
val result=rdd.leftOuterJoin(other);
result.foreach(println);
------
说明:
leftOuterJoin:左外连接,对2个rdd进行连接操作,确保左边(rdd RDD)的键一定存在
结果:
(1,(2,none))
(3,(4,some(9)))
(3,(6,some(9)))
---------------------
val rdd= sc.parallelize(List((1,2),(3,4),(3,6)));
val other= sc.parallelize(List((3,9)));
val result=rdd.rightOuterJoin(other);
result.foreach(println);
------
说明:
rightOuterJoin:右外连接,对2个rdd进行连接操作,确保右边(rdd RDD)的键一定存在
结果:
(3,(some(4),9))
(3,(some(6),9))
---------------------
val rdd= sc.parallelize(List((1,2),(3,4),(3,6)));
val other= sc.parallelize(List((3,9)));
val result=rdd.cogroup(other);
result.foreach(println);
------
说明:
cogroup:将2个RDD拥有相同键的数据分组到一起
结果:
(1,(compactBuffer(2),compactBuffer()))
(3,(compactBuffer(4,6),compactBuffer(9)))
---------------------
三、键值对RDD行动操作实例
和转换操作一样,所有基础RDD支持的传统行动操作也都在pair RDD上可用,除此之外,pair RDD还提供了一些额外的行动操作。
1.例子:countByKey/collectAsMap/lookup(key)
---------------------
val rdd= sc.parallelize(List((1,2),(3,4),(3,6)));
val result=rdd.countByKey();
result.foreach(println);
------
说明:
countByKey:对每个键对应的元素分别计数
结果:
(1,1)
(3,2)
---------------------
val rdd= sc.parallelize(List((1,2),(3,4),(3,6)));
val result=rdd.collectAsMap();
result.foreach(println);
------
说明:
collectAsMap:从结果我们可以看出,如果RDD中同一个Key中存在多个Value,那么后面的Value将会把前面的Value覆盖,最终得到的结果就是Key唯一,而且对应一个Value,《Spark快速大数据分析》第52页给出的结果是不对的。
结果:
(1,2)
(3,6)
---------------------
val rdd= sc.parallelize(List((1,2),(3,4),(3,6)));
val result=rdd.lookup(3);
result.foreach(println);
------
说明:
lookup:返回给定键对应的所有值
结果:
4
6
---------------------
三、参考资料
1.http://blog.csdn.net/gamer_gyt/article/details/51747783,Spark 的键值对(pair RDD)操作,Scala实现
2.http://blog.csdn.net/jiangpeng59/article/details/52538254,Spark核心RDD:combineByKey函数详解
【Spark 深入学习 07】RDD编程之旅基础篇03-键值对RDD的更多相关文章
- 【spark 深入学习 05】RDD编程之旅基础篇-01
---------------- 本节内容 1.RDD的工作流程 2.WordCount解说 · shell版本WordCount · java版本WordCount -------------- ...
- 【spark 深入学习 06】RDD编程之旅基础篇02-Spaek shell
--------------------- 本节内容: · Spark转换 RDD操作实例 · Spark行动 RDD操作实例 · 参考资料 --------------------- 关于学习编程方 ...
- 5.2 RDD编程---键值对RDD
一.键值对RDD的创建 1.从文件中加载 2.通过并行集合(数组)创建RDD 二.常用的键值对RDD转换操作 1.reduceByKey(func) 功能:使用func函数合并具有相同键的值 2.gr ...
- Spark 键值对RDD操作
键值对的RDD操作与基本RDD操作一样,只是操作的元素由基本类型改为二元组. 概述 键值对RDD是Spark操作中最常用的RDD,它是很多程序的构成要素,因为他们提供了并行操作各个键或跨界点重新进行数 ...
- ESP8266开发之旅 基础篇① 走进ESP8266的世界
授人以鱼不如授人以渔,目的不是为了教会你具体项目开发,而是学会学习的能力.希望大家分享给你周边需要的朋友或者同学,说不定大神成长之路有博哥的奠基石... QQ技术互动交流群:ESP8266&3 ...
- ESP8266开发之旅 基础篇③ ESP8266与Arduino的开发说明
授人以鱼不如授人以渔,目的不是为了教会你具体项目开发,而是学会学习的能力.希望大家分享给你周边需要的朋友或者同学,说不定大神成长之路有博哥的奠基石... QQ技术互动交流群:ESP8266&3 ...
- ESP8266开发之旅 基础篇④ ESP8266与EEPROM
授人以鱼不如授人以渔,目的不是为了教会你具体项目开发,而是学会学习的能力.希望大家分享给你周边需要的朋友或者同学,说不定大神成长之路有博哥的奠基石... QQ技术互动交流群:ESP8266&3 ...
- ESP8266开发之旅 基础篇② 如何安装ESP8266的Arduino开发环境
授人以鱼不如授人以渔,目的不是为了教会你具体项目开发,而是学会学习的能力.希望大家分享给你周边需要的朋友或者同学,说不定大神成长之路有博哥的奠基石... QQ技术互动交流群:ESP8266&3 ...
- ESP8266开发之旅 基础篇⑥ Ticker——ESP8266定时库
授人以鱼不如授人以渔,目的不是为了教会你具体项目开发,而是学会学习的能力.希望大家分享给你周边需要的朋友或者同学,说不定大神成长之路有博哥的奠基石... QQ技术互动交流群:ESP8266&3 ...
随机推荐
- Machine Learning 学习笔记2 - linear regression with one variable(单变量线性回归)
一.Model representation(模型表示) 1.1 训练集 由训练样例(training example)组成的集合就是训练集(training set), 如下图所示, 其中(x,y) ...
- springboot springcloud 父项目pom工程创建pom文件
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/20 ...
- 目标检测——IoU 计算
Iou 的计算 我们先考虑一维的情况:令 \(A = [x_1,x_2], B = [y_1, y_2]\),若想要 \(A\) 与 \(B\) 有交集,需要满足如下情况: 简言之,要保证 \(A\) ...
- 【java并发核心二】Exchanger的使用
类 Exchanger 的功能可以使2个线程之间传输数据,比生产者/消费者模式方便. Exchanger类的结构很简单,重点就是exchange()方法. exchange()方法是阻塞执行的,可以设 ...
- Servlet与HTTP介绍学习
http介绍:http是一套规范,一种网络数据交互的标准协议,不同的语言,不同的数据想要实现合理的数据交互(例如:浏览器和服务器数据交互),就得按照他所规定的协议来,这样就会形成标准的(大家都认识的) ...
- AGC027 E - ABBreviate
目录 题目链接 题解 代码 题目链接 AGC027 E - ABBreviate 题解 神仙啊 建议查看https://img.atcoder.jp/agc027/editorial.pdf 定义a ...
- BZOJ.3693.圆桌会议(Hall定理 线段树)
题目链接 先考虑链.题目相当于求是否存在完备匹配.那么由Hall定理,对于任意一个区间[L,R],都要满足[li,ri]完全在[L,R]中的ai之和sum小于等于总位置数,即R-L+1.(其实用不到H ...
- 【漏洞复现】ES File Explorer Open Port Vulnerability - CVE-2019-6447
漏洞描述 在受影响的ES文件浏览器上,会启用59777/tcp端口作为HTTP服务器,攻击者只需要构造恶意的json请求就可以对受害者进行文件下载,应用打开.更可以用过漏洞进行中间人(MITM)攻击. ...
- Hadoop化繁为简(三)—探索Mapreduce简要原理与实践
目录-探索mapreduce 1.Mapreduce的模型简介与特性?Yarn的作用? 2.mapreduce的工作原理是怎样的? 3.配置Yarn与Mapreduce.演示Mapreduce例子程序 ...
- 增益 Gain 分贝 dB
https://zh.wikipedia.org/wiki/%E5%88%86%E8%B2%9D 分贝(decibel)是量度两个相同单位之数量比例的单位,主要用于度量声音强度,常用dB表示. “分” ...