弹性分布式数据集(简称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. Linux内核:关于中断你需要知道的【转】

    转自:http://blog.csdn.net/duqi_2009/article/details/38009717 1.中断处理程序与其他内核函数真正的区别在于,中断处理程序是被内核调用来相应中断的 ...

  2. linux下源码安装netcat

    linux下源码安装netcat http://blog.chinaunix.net/uid-20783755-id-4211230.html 1,下载netcat源码,netcat-0.7.1-13 ...

  3. 如何在qt中使用中文输入法

    参考: http://blog.csdn.net/u013812682/article/details/52101088 dpkg -L fcitx-frontend-qt5 到qt安装目录里find ...

  4. 关于iBatis-selectKey的一点笔记

    技术前提:我们使用iBatis作为持久层方案 技术场景:     假设我们有两张表,一张主表Main,一张子表Sub,并且主表的主键是由数据库维护的自增长的主键,子表中有一个字段引用这个主键,那么当我 ...

  5. nginx [error] open() "/usr/local/nginx/logs/nginx.pid" failed的解决

    今天关闭nginx后重启不了: nginx -s reload 结果报错: nginx: [error] open() "/usr/local/nginx/logs/nginx.pid&qu ...

  6. CvScalar

    CvScalar定义可存放1—4个数值的数值,其结构如下. typedef struct CvScalar{    double val[4];}CvScalar; ----------------- ...

  7. Codeforces 1036E. Covered Points

    又一次写起了几何.... 特殊处理在于有可能出现多条线段交于一点的情况,每次考虑时,对每条线段与其他所有线段的交点存在一个set里,对每一个set,每次删除set.size()即可 重点在于判断两条线 ...

  8. 洛谷——P1163 银行贷款

    P1163 银行贷款 题目描述 当一个人从银行贷款后,在一段时间内他(她)将不得不每月偿还固定的分期付款.这个问题要求计算出贷款者向银行支付的利率.假设利率按月累计. 输入输出格式 输入格式: 输入文 ...

  9. Milk Pails(BFS)

    Milk Pails 时间限制: 1 Sec  内存限制: 64 MB提交: 16  解决: 4[提交][状态][讨论版] 题目描述 Farmer John has received an order ...

  10. awk 精彩文章

    https://coolshell.cn/articles/9070.html 我从netstat命令中提取了如下信息作为用例: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 ...