弹性分布式数据集(简称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 环境变量设置方法总结(PATH/LD_LIBRARY_PATH)

    linux 环境变量设置方法总结(PATH/LD_LIBRARY_PATH) http://blog.csdn.net/wangeen/article/details/8159500 设置 Linux ...

  2. 【反演复习计划】【bzoj1011】zap-queries

    快三个月没做反演题了吧…… 感觉高一上学期学的全忘了…… 所以还得从零开始学推式子. # bzoj1011 标签(空格分隔): 未分类 --- 原题意思是求以下式子:$Ans=\sum\limits_ ...

  3. Android系统是一个基于BInder通信的C/S架构

    Android系统基本上可以看作是一个基于Binder通信的C/S架构.他有服务器端和客户端.比如自己开发一个程序,肯定是基于Activity的而Activity就是作为客户端,他的服务器端就是Act ...

  4. [ Openstack ] OpenStack-Mitaka 高可用之 概述

    目录 Openstack-Mitaka 高可用之 概述    Openstack-Mitaka 高可用之 环境初始化    Openstack-Mitaka 高可用之 Mariadb-Galera集群 ...

  5. --a和a--

    编程很纠结的一个问题便是a--和--a. #include<iostream> using namespace std; int main(int argc, char const *ar ...

  6. [libgdx游戏开发教程]使用Libgdx进行游戏开发(11)-高级编程技巧 Box2d和Shader

    高级编程技巧只是相对的,其实主要是讲物理模拟和着色器程序的使用. 本章主要讲解利用Box2D并用它来实现萝卜雨,然后是使用单色着色器shader让画面呈现单色状态:http://files.cnblo ...

  7. 《javascript高级程序设计》读书小延伸

    这本书已经读了几章了,想着试试能不能做出点东西,就简单的练了把手.觉得对于初学者,自己试着练练,效果还不错的. 挥刀要从轻的开始,起初的原因是和同事谈起曾经的逝水年华(小时候干的坏事)时说起了曾经的一 ...

  8. UVA 10340 All in All(字符串,朴素匹配)

    #include <stdio.h> #include <algorithm> #include <cstring> using namespace std; ], ...

  9. Linux命令之vim(二)

    这一章主要介绍vim编辑器的内部使用方法和注意事项 vim编辑器有四种工作模式:正常模式.插入模式.命令模式.可视模式.简单的判断方法就是看底部,什么都没有就是正常模式,光标在编辑器最底下时则是命令模 ...

  10. java应用高内存占用

    在java虚拟机中,内存分为三个代:新生代(New), 老生代(Old).永久代(Perm) 新生代: 新建的对象都存放这里老生代:存放从新生代中迁移过来的生命周期较久的对象.新生代和老生代共同组成了 ...