弹性分布式数据集(简称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自学三)的更多相关文章

  1. Spark(三)RDD与广播变量、累加器

    一.RDD的概述 1.1 什么是RDD RDD(Resilient Distributed Dataset)叫做弹性分布式数据集,是Spark中最基本的数据抽象,它代表一个不可变.可分区.里面的元素可 ...

  2. Learning Spark中文版--第三章--RDD编程(2)

    Common Transformations and Actions   本章中,我们浏览了Spark中大多数常见的transformation(转换)和action(开工).在包含特定数据类型的RD ...

  3. Learning Spark中文版--第三章--RDD编程(1)

       本章介绍了Spark用于数据处理的核心抽象概念,具有弹性的分布式数据集(RDD).一个RDD仅仅是一个分布式的元素集合.在Spark中,所有工作都表示为创建新的RDDs.转换现有的RDD,或者调 ...

  4. 【spark 深入学习 06】RDD编程之旅基础篇02-Spaek shell

    --------------------- 本节内容: · Spark转换 RDD操作实例 · Spark行动 RDD操作实例 · 参考资料 --------------------- 关于学习编程方 ...

  5. Spark学习笔记2:RDD编程

    通过一个简单的单词计数的例子来开始介绍RDD编程. import org.apache.spark.{SparkConf, SparkContext} object word { def main(a ...

  6. Spark菜鸟学习营Day1 从Java到RDD编程

    Spark菜鸟学习营Day1 从Java到RDD编程 菜鸟训练营主要的目标是帮助大家从零开始,初步掌握Spark程序的开发. Spark的编程模型是一步一步发展过来的,今天主要带大家走一下这段路,让我 ...

  7. Spark RDD编程核心

    一句话说,在Spark中对数据的操作其实就是对RDD的操作,而对RDD的操作不外乎创建.转换.调用求值. 什么是RDD RDD(Resilient Distributed Dataset),弹性分布式 ...

  8. Spark学习之RDD编程总结

    Spark 对数据的核心抽象——弹性分布式数据集(Resilient Distributed Dataset,简称 RDD).RDD 其实就是分布式的元素集合.在 Spark 中,对数据的所有操作不外 ...

  9. 【spark 深入学习 05】RDD编程之旅基础篇-01

    ---------------- 本节内容 1.RDD的工作流程 2.WordCount解说  · shell版本WordCount  · java版本WordCount -------------- ...

随机推荐

  1. arm处理器中a5 a8 a9,v6 v7,arm7 arm9 arm11都是依据什么来分类的【转】

    转自:http://blog.csdn.net/maochengtao/article/details/9951131ARM处理器发展这么多年,有很多架构,很多不同的内核 架构有armv1 v2 v3 ...

  2. decimal数据类型

    DECIMAL(N,M)中M是小数部分的位数,若插入的值未指定小数部分或者小数部分不足M位则会自动补到M位小数,若插入的值小数部分超过了M为则会发生截断,截取前M位小数. N是整数部分加小数部分的总长 ...

  3. windows下nginx安装及使用

    nginx简介: nginx是一款轻量级web服务器,也是一款反向代理服务器(比如域名转发等). nginx功能: 1.可直接支持Rails和PHP的程序. 2.可作为HTTP反向代理服务器. 3.作 ...

  4. Anaconda 2和3在Win10上共存

    1. 安装Anaconda 2和3 Anaconda 2中的python2为主,Anaconda 3中的python3为辅.先装Anaconda 2,并在安装时选择注册为系统python,再装Anac ...

  5. 查看Linux上的CPU核心数、线程数

    grep "physical id" /proc/cpuinfo|sort -u grep "cpu cores" /proc/cpuinfo|uniq gre ...

  6. [ 总结 ] vsftpd 虚拟用户配置

    需求:在不更改目录权限的前提下,ftp用户对目录里的文件拥有所有权. [root@server2 ~]# yum install vsftpd -y [root@server2 ~]# cd /etc ...

  7. Ubuntu16.04 PPA方式安装JDK1.8

    一.删除OpenJDK:   sudo apt-get purge openjdk* 二.添加PPA: root@ubuntu:~# add-apt-repository ppa:webupd8tea ...

  8. Tkinter 小应用

    import tkinter as tk class APP: def __init__(self,master): frame = tk.Frame(master) frame.pack(side ...

  9. solr in action 第三章

    document: 每个document由一个或者多个域(field)组成,每个域都有自己的类型:string, text, etc. 理论上域的类型有无限多个,因为一个域的类型可以由零个或多个分析阶 ...

  10. 【LeedCode】String to integer(atoi)

    Implement atoi to convert a string to an integer. Hint: Carefully consider all possible input cases. ...