本篇博客中的操作都在 ./bin/pyspark 中执行。

RDD,即弹性分布式数据集(Resilient Distributed Dataset),是Spark对数据的核心抽象。RDD是分布式元素的集合,对手的所有操作都可以概括为:

  • 创建RDD
  • 转化已有RDD
  • 调用RDD操作进行求值

在这些操作中,Spark会自动将RDD中的数据分发的集群上,并将操作自动化执行。

每个RDD都被分为多个分区,这些分区运行在集群中的不同节点上。

Get Started

用户可以:

  • 读取一个外部数据集
  • 或者使用对象集合(比如 list 或者 set)

来创建 RDD。比如使用 SparkContext.textFile() 来创建一个字符串RDD:

lines = sc.textFile("README.md")

RDD创建之后,支持:

  • 转化操作(transformation):会由一个RDD生成一个新的RDD。
  • 行动操作(action):会计算出一个结果,并把结果返回到驱动器程序中,或存储在外部存储系统中。

Spark对RDD是惰性计算的,只有在行动操作(action)时,才会真正计算。

回到shell 中,再执行:

pythonLines = lines.filter(lambda line: "Python" in line)

行动操作 first() 之中,Spark才进行真正的计算,而这时候只需要计算结果中真正需要的数据:在这里,Spark只需要扫面文件知道找到第一个匹配的行(包含"Python"的行)就停止了。

默认情况下,Spark的RDD会在每次进行行动(Action)操作的时候重新计算,如果想在多个行动操作中使用同一个RDD,可以使用.persist()方法来让Spark把这个RDD缓存下来,这个操作叫做:持久化。

持久化方便在以后的操作中重用数据。

总的来说,Spark会这样工作:

  1. 创建出RDD
  2. 使用转化操作(比如filter)对RDD进行转化,创建出新RDD
  3. 告诉Spark我们要重用哪些中间结果,对这些RDD进行持久化操作
  4. 使用行动(Action)操作,来触发一次计算,Spark会对计算进行优化后再执行。

另:cache()persist() 使用的默认存储级别是一样的。

创建一个RDD

使用外部数据集的方式比较常见,这里我们就看一个文本文档的例子:

lines = sc.textFile("README.md")

为了下面的演示不麻烦,我们这里主要看通过将程序中的集合转化为RDD的方法,快速创建一个RDD:

lines = sc.parallelize(["Hello world", "News about Senate Hacking Hearing","US official says Russia undoubtedly meddled in US election"])

// 注意上面的RDD中出现了两个"US",后面有用。

对进行RDD操作

RDD的转化操作是返回一个新的RDD的操作,比如.filter()操作就是转化操作。

RDD的行动操作是向驱动器程序返回结果,或者把结果写入外部驱动器,行动操作会触发实际的计算,比如.count()或者 .first()方法。

转化操作

场景:找了个自己以前程序的log文件,我们使用Spark找出其中的错误(ERROR)信息,文件link

下面是使用.filter()实现转化操作:

>>> inputRDD   =  sc.textFile("url_Requests.log")
>>> errorsRDD = inputRDD.filter(lambda x : "ERROR" in x)
>>> cautionRDD = inputRDD.filter(lambda x : "CAUTION" in x)

注意 .filter() 方法不会改变已有的 inputRDD 中的数据,该操作会返回一个全新的RDD,inputRDD还在后面的程序中还可以继续使用。

然后再来一个.union() 操作:

>>> badlineRDD = errorsRDD.union(cautionRDD)

.union() 操作就是取并集,这个还比较好理解。

通过转化操作,可以从已有的RDD中派生出新的RDD。

行动(action)操作

比如说.count()操作,就是一个行动操作:

另外一个常见的操作是.collect():

对于.collect()操作来说,可以用来获取整个RDD中的数据。只有当整个RDD的数据能在单台机器的内存中放得下时,才能使用该方法。

当我们每次调用一个新的行动操作时,整个RDD都会从头开始计算,如果要避免这种行为,用户可以让中间结果持久化,这个在后面会提到。

关于惰性求值

RDD的转化都是惰性求值的,就是说在被调用行动曹组偶之前,Spark不会开始计算。

惰性求值以为这我们对RDD调用转化操作是,操作不会立即执行,Spark会在内部记录下所有要执行的操作信息。我们可以把RDD当成我们通过转化操作构建出来的特定数据集。

上面操作过的把文本数据读到RDD的操作同样也是惰性的,当我们调用 sc.textFile()时,数据并没有读取进来,而是在必要时才会读取。 和转化操作相同的是,读取数据的操作也有可能被多次执行。

常见RDD的转化操作和行动操作

对各个元素的转化操作

其中的一个例子是 .map()方法,map可以对RDD中的每个数据进行操作:

>>> nums = sc.parallelize([1,2,3,4])
>>> squared = nums.map(lambda x : x ** 2)
>>> squared.collect()
[1, 4, 9, 16]

再比如我们刚才的日志文件:

>>> numberOfLines = errorsRDD.map(lambda line: len(line))
>>> numberOfLines.collect()

这里,我们计算了每行错误日志的字符数,结果为:

另一个是flatMap,看一个例子就懂了,还记得我们刚才创建的lines吗:

lines.collect()
words = lines.flatMap(lambda line: line.split(" "))
words.collect()

其输出结果为:

.map() 有什么区别呢,这是 map 的输出结果,很容易懂:

使用 .distinct() 操作进行去重:

常见行动操作

.reduce() 是最常用的行动操作:

reduce 接受一个函数作为参数,这个函数要操作2个相同元素类型的RDD数据,并返回一个同样类型的新元素。

此外,还有toptake 等常见操作:

[Spark] Spark的RDD编程的更多相关文章

  1. 02、体验Spark shell下RDD编程

    02.体验Spark shell下RDD编程 1.Spark RDD介绍 RDD是Resilient Distributed Dataset,中文翻译是弹性分布式数据集.该类是Spark是核心类成员之 ...

  2. Spark学习之RDD编程(2)

    Spark学习之RDD编程(2) 1. Spark中的RDD是一个不可变的分布式对象集合. 2. 在Spark中数据的操作不外乎创建RDD.转化已有的RDD以及调用RDD操作进行求值. 3. 创建RD ...

  3. spark实验(四)--RDD编程(1)

    一.实验目的 (1)熟悉 Spark 的 RDD 基本操作及键值对操作: (2)熟悉使用 RDD 编程解决实际具体问题的方法. 二.实验平台 操作系统:centos6.4 Spark 版本:1.5.0 ...

  4. spark 中的RDD编程 -以下基于Java api

    1.RDD介绍:     RDD,弹性分布式数据集,即分布式的元素集合.在spark中,对所有数据的操作不外乎是创建RDD.转化已有的RDD以及调用RDD操作进行求值.在这一切的背后,Spark会自动 ...

  5. Spark学习之RDD编程总结

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

  6. Spark学习笔记——RDD编程

    1.RDD——弹性分布式数据集(Resilient Distributed Dataset) RDD是一个分布式的元素集合,在Spark中,对数据的操作就是创建RDD.转换已有的RDD和调用RDD操作 ...

  7. Spark学习(2) RDD编程

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

  8. Spark(四)【RDD编程算子】

    目录 测试准备 一.Value类型转换算子 map(func) mapPartitions(func) mapPartitions和map的区别 mapPartitionsWithIndex(func ...

  9. Spark菜鸟学习营Day3 RDD编程进阶

    Spark菜鸟学习营Day3 RDD编程进阶 RDD代码简化 对于昨天练习的代码,我们可以从几个方面来简化: 使用fluent风格写法,可以减少对于中间变量的定义. 使用lambda表示式来替换对象写 ...

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

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

随机推荐

  1. C语言中printf的规范输出

    1.调用格式为  printf("<格式化字符串>", <参量表>);   其中格式化字符串包括两部分内容: 一部分是正常字符, 这些字符将按原样输出; 另 ...

  2. 初识django

    一 从下面开始 所有的的web应用其实就是就是一个socket服务器,浏览器是一个web客户端. import socket def handle_request(client): buf = cli ...

  3. Python 代码覆盖率统计工具 coverage.py

    coverage.py是一个用来统计python程序代码覆盖率的工具.它使用起来非常简单,并且支持最终生成界面友好的html报告.在最新版本中,还提供了分支覆盖的功能. 官方网站: http://ne ...

  4. oracle中函数和存储过程的区别和联系【转载竹沥半夏】

    oracle中函数和存储过程的区别和联系[转载竹沥半夏] 在oracle中,函数和存储过程是经常使用到的,他们的语法中有很多相似的地方,但也有自己的特点.刚学完函数和存储过程,下面来和大家分享一下自己 ...

  5. php 入门1

    一.php在引入文件和js引入文件的区别 1.php在引入文件是用代码控制,而js是通过标签的属性src引入: 2.php引入可以在引入下写代码,而js是不可以的 3.静态效果的js可以引入的时间,引 ...

  6. 17+个ASP.NET MVC扩展点【附源码】

    1.自定义一个HttpModule,并将其中的方法添加到HttpApplication相应的事件中!即:创建一个实现了IHttpmodule接口的类,并将配置WebConfig.  在自定义的Http ...

  7. Java内存区域与内存溢出异常

    Java与C++之间有一堵由内存动态分配和垃圾收集技术所围成的“高墙”. Java将内存控制的权利交给了Java虚拟机,一旦出现内存泄露和溢出问题,如果不了解虚拟机是怎样使用内存的,那么排查错误将会成 ...

  8. jQuery EasyUI 使用笔记

    大家有四次抢票机会.第一次是放票时间之后的30分钟.第二次机会是开车前的15天.第三个机会是开车前的48小时.第四个机会是开车前的24小时. $("#gys_key").combo ...

  9. MAC下彻底解决mysql无法插入和显示中文

    一.场景呈现 Mac 下Eclipse+mysql开发j2ee的时候,在页面像数据库中插入中文数据的时候,数据库会报错.而且即使插入成功,在控制台或者其他可视化数据库操作软件看数据发现都是??,错误的 ...

  10. 【原创】Android ExpandableListView使用

    ExpandableView的使用可以绑定到SimpleExpandableListAdapter,主要是看这个Adapter怎么用. 这个类默认的构造函数有9个参数, 很好地解释了什么叫做又臭又长. ...