RDD编程 上(Spark自学三)
弹性分布式数据集(简称RDD)是Spark对数据的核心抽象。RDD其实就是分布式的元素集合。在Spark中,对数据的操作不外乎创建RDD、转化已有RDD以及调用RDD操作进行求值。而在这一切背后,Spark会自动将RDD中的数据分发到集群上,并将操作并行化执行。
3.1 RDD基础
Spark中的RDD就是一个不可变的分布式对象集合。每个RDD都被分为多个分区,这些分区运行在集群中的不同节点上。
例3-1:在Python中使用textFile()创建一个字符串的RDD
lines = sc.textFile("README.md")
创建出来后,RDD支持两种类型的操作:转化操作和行动操作。转化操作会由一个RDD生成一个新的RDD。行动操作会对RDD计算出一个结果,并把结果返回到驱动器程序中,或把结果存储到外部存储系统(如HDFS)中。
例3-2:调用转化操作filter()
pythonLines = lines.filter(lambda line:"python" in line)
例3-3:调用first()行动操作
pythonLines.first()
Spark只会惰性计算这些RDD。它们只有第一次在一个行动操作中用到时,才会真正计算。Spark了解了完整的转化操作链之后,它就可以只计算求结果时真正需要的数据。
默认情况下,Spark的RDD会在你每次对它们进行行动操作时重新计算。如果想在多个行动操作中重用同一个RDD,可以使用RDD.persist()让Spark把这个RDD缓存下来。在第一次对持久化的RDD计算之后,Spark会把RDD的内容保存在内存中(以分区方式存储到集群中的各个机器上)。
例3-4:把RDD持久化到内存中
pythonLines.persist()
pythonLines.count()
pythonLines.first()
3.2 创建RDD
Spark提供了两种创建RDD的方式:1读取外部数据集,2在驱动器程序中对一个集合进行并行化。
创建RDD最简单的方式就是把程序中一个已有的集合传给SparkContext的parallelize()方法,这种方式用的并不多,毕竟需要把整个数据集先放在一台机器的内存中。
例3-5:Python中的parallelize()方法
lines = sc.parallelize(["pandas", "i like pandas"])
例3-6:Scala中的parallelize()方法
val lines = sc.parallelize(List("pandas", "i like pandas"))
更常用的方式是从外部存储中读取数据来创建RDD。
例3-8 : Python中的textFile()方法
lines = sc.textFile("/path/to/README.md")
例3-9:Scala中的textFile()方法
val lines = sc.textFile("/path/to/README.md")
3.3 RDD操作
3.3.1 转化操作
RDD的转化操作是返回新RDD的操作。
例 3-11:用Python实现filter()转化操作
inputRDD = sc.textFile("log.txt")
errorsRDD = inputRDD.filter(lambda x: "error" in x)
例 3-12:用Scala实现filter()转化操作
val inputRDD = sc.textFile("log.txt")
val errorsRDD = inputRDD.filter(line => line.contains("error"))
filter()操作不会改变已有的inputRDD中的数据
例 3-14:用Python进行union()转化操作
errorsRDD = inputRDD.filter(lambda x:"error" in x)
warningsRDD = inputRDD.filter(lambda x:"warning" in x)
badlLinesRDD = errorsRDD.union(warningsRDD)
通过转化操作,我们从已有的RDD中派生出新的RDD,Spark会使用谱系图来记录这些不同RDD之间的依赖关系。Spark需要用这些信息来按需计算每个RDD,也可以依靠谱系图在持久化的RDD丢失部分数据时恢复所丢失的数据。
3.3.2 行动操作
行动操作会对数据集进行实际的计算,把最终求得的结果返回到驱动器程序,或者写入外部存储系统中。行动操作会强制执行那些求值必须用到的RDD的转化操作。
例3-15:在Python中使用行动操作对错误进行计数
print "Input had" + badLinesRDD.count() + "concerting lines"
for line in badLinesRDD.take(10):
print line
例3-16:在Scala中使用行动操作对错误进行计数
println("Input had " + badLinesRDD.count() + " concerning lines")
badLinesRDD.take(10).foreach(println)
每当我们调用一的新的行动操作时,整个RDD都会从头开始计算。要避免这种低效的行为,我们可以将中间结果持久化。
3.3.3 惰性求值
我们不应该把RDD看作存放着特定数据的数据集,而最好把每个RDD当作我们通过转化操作构建出来的、记录如何生成新数据集的指令列表。
在Spark中,一个非常复杂的映射不会比使用很多简单的连续操作获得更好的性能。
3.4 向Spark传递函数
Spark的大部分转化操作和一部分行动操作,都需要依赖用户传递的函数来计算
3.4.1 Python
例 3-18:在Python中传递函数
word = rdd.filter(lambda s : "error" in s) def containsError(s):
return "error" in s
word = rdd.filter(containsError)
传递函数时需要小心的一点是,Python会在你不经意间把函数所在的对象也序列化传出去。
替代方案是,只把我们所需要的字段从对象中拿出来放到一个局部变量中,然后传递这个局部变量。
例3-20:传递不带字段引用的Python函数
class WordFunstions(object):
def __init__(self, query):
self.query = query
def func(self, rdd):
query = self.query
return rdd.filter(lambda x: query in x)
3.4.2 Scala
与Python类似,传递一个对象的方法或者字段时,会包含对整个对象的引用。
我们可以把需要的字段放到一个局部变量中,来避免传递包含该字段的整个对象。
class SearchFunctions(val query: String){
def getMatchesNoReference(rdd: RDD[String]):RDD[String] = {
val query_ = this.query
rdd.map(x => x.split(query_))
}
}
RDD编程 上(Spark自学三)的更多相关文章
- Spark(三)RDD与广播变量、累加器
一.RDD的概述 1.1 什么是RDD RDD(Resilient Distributed Dataset)叫做弹性分布式数据集,是Spark中最基本的数据抽象,它代表一个不可变.可分区.里面的元素可 ...
- Learning Spark中文版--第三章--RDD编程(2)
Common Transformations and Actions 本章中,我们浏览了Spark中大多数常见的transformation(转换)和action(开工).在包含特定数据类型的RD ...
- Learning Spark中文版--第三章--RDD编程(1)
本章介绍了Spark用于数据处理的核心抽象概念,具有弹性的分布式数据集(RDD).一个RDD仅仅是一个分布式的元素集合.在Spark中,所有工作都表示为创建新的RDDs.转换现有的RDD,或者调 ...
- 【spark 深入学习 06】RDD编程之旅基础篇02-Spaek shell
--------------------- 本节内容: · Spark转换 RDD操作实例 · Spark行动 RDD操作实例 · 参考资料 --------------------- 关于学习编程方 ...
- Spark学习笔记2:RDD编程
通过一个简单的单词计数的例子来开始介绍RDD编程. import org.apache.spark.{SparkConf, SparkContext} object word { def main(a ...
- Spark菜鸟学习营Day1 从Java到RDD编程
Spark菜鸟学习营Day1 从Java到RDD编程 菜鸟训练营主要的目标是帮助大家从零开始,初步掌握Spark程序的开发. Spark的编程模型是一步一步发展过来的,今天主要带大家走一下这段路,让我 ...
- Spark RDD编程核心
一句话说,在Spark中对数据的操作其实就是对RDD的操作,而对RDD的操作不外乎创建.转换.调用求值. 什么是RDD RDD(Resilient Distributed Dataset),弹性分布式 ...
- Spark学习之RDD编程总结
Spark 对数据的核心抽象——弹性分布式数据集(Resilient Distributed Dataset,简称 RDD).RDD 其实就是分布式的元素集合.在 Spark 中,对数据的所有操作不外 ...
- 【spark 深入学习 05】RDD编程之旅基础篇-01
---------------- 本节内容 1.RDD的工作流程 2.WordCount解说 · shell版本WordCount · java版本WordCount -------------- ...
随机推荐
- a标签里文本居中
text-align:center; height: 30px; line-height:30px;
- PL/SQL 04 游标 cursor
--游标 declare cursor 游标名字 is 查询语句;begin 其他语句;end; --游标的属性%FOUND%NOTFOUND%ISOPEN%ROWCOUNT(当前游标的指针位 ...
- [ 总结 ] RHEL6/Centos6 使用OpenLDAP集中管理用户帐号
使用轻量级目录访问协议(LDAP)构建集中的身份验证系统可以减少管理成本,增强安全性,避免数据复制的问题,并提供数据的一致性.
- idea打包jar的多种方式,用IDEA自带的打包形式,用IDEA自带的打包形式 用Maven插件maven-shade-plugin打包,用Maven插件maven-assembly-plugin打包
这里总结出用IDEA打包jar包的多种方式,以后的项目打包Jar包可以参考如下形式: 用IDEA自带的打包形式 用Maven插件maven-shade-plugin打包 用Maven插件maven-a ...
- win32 sdk列表视图控件(ListCtrl或ListView)资料整理
列表视图控件是一种非常常用的控件,在需要以报表形式显示数据时,列表控件通常是最好的选择,许多专用的数据报表控件,也是在它的基础上派生而来.与树视图类似,列表控件可以由多个子项目组成,可以设置为Icon ...
- CentOS7 中把默认yum源更换成163源
163源是目前国内最好用的源,速度是相当快的,现在我们把CentOS7中的源改为163源 1.进入yum源配置文件 cd /etc/yum.repos.d 2.备份一下当前的源,以防出错后可以还原回来 ...
- CF 996B World Cup 【找规律/模拟】
CF [题意]:圆形球场有n个门,Allen想要进去看比赛.Allen采取以下方案进入球场:开始Allen站在第一个门,如果当前门前面有人Allen会花费单位时间走到下一个门,如果没人Allen从这个 ...
- HDU 2044 一只小蜜蜂(递归)
一只小蜜蜂... Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Su ...
- 主席树【bzoj3524(p3567)】[POI2014]Couriers
Description 给一个长度为n的序列a.1≤a[i]≤n. m组询问,每次询问一个区间[l,r],是否存在一个数在[l,r]中出现的次数大于(r-l+1)/2.如果存在,输出这个数,否则输出0 ...
- 【Android】自定义View
内置组件经常不满足我们的需求,那么就要自己来重写了,一般需要实现以下几个父类方法: 1.onMeasure 决定内部View的宽和高,以及自身的宽和高 2.onLayout 决定子View的放置位置 ...