1.RDD——弹性分布式数据集(Resilient Distributed Dataset)

RDD是一个分布式的元素集合,在Spark中,对数据的操作就是创建RDD转换已有的RDD调用RDD操作进行求值

Spark 中的 RDD 就是一个不可变的分布式对象集合。每个 RDD 都被分为多个分区,这些分区运行在集群中的不同节点上。

object WordCount {
def main(args: Array[String]) {
val inputFile = "file:///home/common/coding/coding/Scala/word-count/test.segmented"
val conf = new SparkConf().setAppName("WordCount").setMaster("local")    #创建一个SparkConf对象来配置应用<br>    #集群URL:告诉Spark连接到哪个集群,local是单机单线程,无需连接到集群,应用名:在集群管理器的用户界面方便找到应用
val sc = new SparkContext(conf)        #然后基于这SparkConf创建一个SparkContext对象
val textFile = sc.textFile(inputFile)    #读取输入的数据
val wordCount = textFile.flatMap(line => line.split(" ")).map(word => (word, 1)).reduceByKey((a, b) => a + b)  #切分成单词,转换成键值对并计数
wordCount.foreach(println)
}
}

创建一个RDD

val textFile = sc.textFile(inputFile)

或者

val lines = sc.parallelize(List("pandas", "i like pandas"))

RDD支持两种类型的操作: 转化操作(transformation)行动操作(action)

转化操作,是返回一个新的RDD的操作:

filter()函数

val RDD = textFile.filter(line => line.contains("Hadoop"))

map()函数

val input = sc.parallelize(List(1, 2, 3, 4))
val result = input.map(x => x * x)
println(result.collect().mkString(","))

输出

1,4,9,16

map()和flatMap()的区别

    val input1 = sc.parallelize(List("hello world","hi"))
val lines = input1.map(line => line.split(" "))
for(line <- lines)
println(line)  //输出是两个List的地址
val lines_ = input1.flatMap(line => line.split(" "))
for(line_ <- lines_)
println(line_)  //输出是[hello world hi]

行动操作,是向驱动器程序返回结果或把结果写入外部系统的操作,会触发实际的计算:first()、count()、take()、collect()[获取整个RDD中的数据,只有想在本地处理这些数据的时候,才可以使用,因为一般情况下RDD很大]

take()函数

textFile.take(5).foreach(println)

reduce函数,接收一个函数作为参数

val input = sc.parallelize(List(1, 2, 3, 4))
val sum = input.reduce((x, y) => x + y)
println(sum)  //输出1-4的累加和,10

aggregate()函数,计算List的和以及List的元素个数,然后计算平均值

    val input = sc.parallelize(List(1, 2, 3, 4))
val result = input.aggregate((0, 0))(
(acc, value) => (acc._1 + value, acc._2 + 1),
(acc1, acc2) => (acc1._1 + acc2._1, acc1._2 + acc2._2))
val avg = result._1 / result._2.toDouble
println(result)
println(avg)

输出

(10,4)
2.5

对于

val sum1 = input.aggregate((0, 0))((x, y) => (x._1 + y, x._2 + 1), (x, y) => (x._1 + y._1, x._2 + y._2))

输出(10,4)

理解

过程大概这样:

首先,初始值是(0,0),这个值在后面2步会用到。

然后,(acc,number) => (acc._1 + number, acc._2 + 1),number即是函数定义中的T,这里即是List中的元素。所以acc._1 + number, acc._2 + 1的过程如下。

    1.   0+1,  0+1

    2.  1+2,  1+1

    3.  3+3,  2+1

    4.  6+4,  3+1

    5.  10+5,  4+1

    6.  15+6,  5+1

    7.  21+7,  6+1

    8.  28+8,  7+1

    9.  36+9,  8+1

结果即是(45,9)。这里演示的是单线程计算过程,实际Spark执行中是分布式计算,可能会把List分成多个分区,假如3个,p1(1,2,3,4),p2(5,6,7,8),p3(9),经过计算各分区的的结果(10,4),(26,4),(9,1),这样,执行(par1,par2) => (par1._1 + par2._1, par1._2 + par2._2)就是(10+26+9,4+4+1)即(45,9).再求平均值就简单了。

top()函数,可以返回RDD的前几个元素

fold()函数,和reduce()函数的功能差不多,但是需要提供初始值

val numbers = List(1, 2, 3, 4)
println(
numbers.fold(1) {
(a, b) => a + b
}
)

输出11

转化操作和行动操作的区别:

1.转换操作只会惰性计算这些 RDD

2.行动操作会对 RDD 计算出一个结果,并把结果返回到驱动器程序中,或把结果存储到外部存储系统(如 HDFS)中

默认情况下,Spark 的 RDD 会在你每次对它们进行行动操作时重新计算。如果想在多个行动操作中重用同一个 RDD,可以使用 RDD.persist() 让 Spark 把这个 RDD 缓存下来

2.向Spark传递函数

在 Scala 中,我们可以把定义的内联函数、方法的引用或静态方法传递给 Spark。

我们可以把需要的字段放到一个局部变量中,来避免传递包含该字段的整个对象

class SearchFunctions(val query: String) {

    def isMatch(s: String): Boolean = {
s.contains(query)
} def getMatchesFunctionReference(rdd: RDD[String]): RDD[String] = {
// 问题: "isMatch"表示"this.isMatch",因此我们要传递整个"this"
rdd.map(isMatch)
} def getMatchesFieldReference(rdd: RDD[String]): RDD[String] = {
// 问题: "query"表示"this.query",因此我们要传递整个"this"
rdd.map(x => x.split(query))
} def getMatchesNoReference(rdd: RDD[String]): RDD[String] = {
// 安全:只把我们需要的字段拿出来放入局部变量中
val query_ = this.query
rdd.map(x => x.split(query_))
}
}

3.持久化(缓存)

Spark RDD 是惰性求值的,而有时我们希望能多次使用同一个 RDD的时候需要对RDD进行持久化

两次调用行动操作,每次Spark都会重新计算RDD和它的所有依赖

val result = input.map(x => x*x)
println(result.count())
println(result.collect().mkString(","))

使用persist()来进行持久化

val result = input.map(x => x * x)
result.persist(StorageLevel.DISK_ONLY)
println(result.count())
println(result.collect().mkString(","))

如果要缓存的数据太多,内存中放不下,Spark 会自动利用最近最少使用(LRU)的缓存策略把最老的分区从内存中移除。

RDD 还有一个方法叫作 unpersist() ,调用该方法可以手动把持久化的 RDD 从缓存中移除。

Spark学习笔记——RDD编程的更多相关文章

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

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

  2. Spark学习之RDD编程总结

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

  3. Spark学习(2) RDD编程

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

  4. Spark学习笔记3——RDD(下)

    目录 Spark学习笔记3--RDD(下) 向Spark传递函数 通过匿名内部类 通过具名类传递 通过带参数的 Java 函数类传递 通过 lambda 表达式传递(仅限于 Java 8 及以上) 常 ...

  5. Spark学习笔记2——RDD(上)

    目录 Spark学习笔记2--RDD(上) RDD是什么? 例子 创建 RDD 并行化方式 读取外部数据集方式 RDD 操作 转化操作 行动操作 惰性求值 Spark学习笔记2--RDD(上) 笔记摘 ...

  6. spark学习笔记总结-spark入门资料精化

    Spark学习笔记 Spark简介 spark 可以很容易和yarn结合,直接调用HDFS.Hbase上面的数据,和hadoop结合.配置很容易. spark发展迅猛,框架比hadoop更加灵活实用. ...

  7. Spark学习笔记0——简单了解和技术架构

    目录 Spark学习笔记0--简单了解和技术架构 什么是Spark 技术架构和软件栈 Spark Core Spark SQL Spark Streaming MLlib GraphX 集群管理器 受 ...

  8. Spark学习笔记之SparkRDD

    Spark学习笔记之SparkRDD 一.   基本概念 RDD(resilient distributed datasets)弹性分布式数据集. 来自于两方面 ①   内存集合和外部存储系统 ②   ...

  9. Spark学习笔记-GraphX-1

    Spark学习笔记-GraphX-1 标签: SparkGraphGraphX图计算 2014-09-29 13:04 2339人阅读 评论(0) 收藏 举报  分类: Spark(8)  版权声明: ...

随机推荐

  1. Codeforces757E.Bash Plays With Functions(积性函数 DP)

    题目链接 \(Description\) q次询问,每次给定r,n,求\(F_r(n)\). \[ f_0(n)=\sum_{u\times v=n}[(u,v)=1]\\ f_{r+1}(n)=\s ...

  2. Loadrunner11的安装方法和破解

    前提:我使用的是在虚拟机下安装32位win7系统,浏览器为IE8(为录制脚本做铺垫) LoadRunner,是一种预测系统行为和性能的负载测试工具.通过以模拟上千万用户实施并发负载及实时性能监测的方式 ...

  3. Wed 基础

    HTTP协议 www服务应用的默认端口为80 https加密服务的默认端口为443 常见状态码及其对应的作用 http://oldboy.blog.51cto.com/2561410/716294 2 ...

  4. yum 安装 jenkins

    环境:已安装 tomcat 安装(如果yum下载速度比较忙可以下载下来再安装) yum -y install https://pkg.jenkins.io/redhat/jenkins-2.77-1. ...

  5. ADSL理解

    ADSL技术提供的上行和下行带宽不对称,因此称为非对称数字用户线路. ADSL技术采用频分复用技术把普通的电话线分成了电话.上行和下行三个相对独立的信道,从而避免了相互之间的干扰.用户可以边打电话边上 ...

  6. extern字符串常量,宏定义字符串常量,怎么选

    在使用常量的时候,我看到主要有两种写法: #define RKLICURegexEnumerationOptionsErrorKey @"RKLICURegexEnumerationOpti ...

  7. 你真的会用Gson吗?Gson使用指南(2)

    注:此系列基于Gson 2.4. 上一篇文章 你真的会用Gson吗?Gson使用指南(1) 我们了解了Gson的基础用法,这次我们继续深入了解Gson的使用方法. 本次的主要内容: Gson的流式反序 ...

  8. 如何用 async 控制流程

    来自: http://larry850806.github.io/2016/05/31/async/ [Javascript] 如何用 async 控制流程 (一) 31 May 2016 async ...

  9. ELK菜鸟手记 (一) 环境配置+log4j日志记录

    1. 背景介绍 在大数据时代,日志记录和管理变得尤为重要. 以往的文件记录日志的形式,既查询起来又不方便,又造成日志在服务器上分散存储,管理起来相当麻烦, 想根据一个关键字查询日志中某个关键信息相当困 ...

  10. 系统编码、文件编码与python系统编码

    在linux中获取系统编码结果: Windows系统的编码,代码页936表示GBK编码 可以看到linux系统默认使用UTF-8编码,windows默认使用GBK编码.Linux环境下,文件默认使用U ...