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. 潭州课堂25班:Ph201805201 python 模块 datetime,logging 第七课 (课堂笔记)

    datetime 模块 # -*- coding: utf-8 -*-# 斌彬电脑# @Time : 2018/7/9 0009 20:42import datetime d = datetime.d ...

  2. mongoDB进行分组操作

    一.$group 进行分组 1.每个职位的雇员人数: db.getCollection('emp').aggregate( [ {'$group':{ ‘_id’:'$job', job_count: ...

  3. JS 显示周 几和 月 日

    function getMyDay(date){ var week; ; var day = date.getDate(); ) week="周日" ) week="周一 ...

  4. 47. 全排列 II

    47. 全排列 II 题意 给定一个可包含重复数字的序列,返回所有不重复的全排列. 示例: 输入: [1,1,2]输出:[ [1,1,2], [1,2,1], [2,1,1]] 解题思路 去重的全排列 ...

  5. 2D Tookit简单教程

    1. 在Project Window中点击Create > tk2d > Sprite Collection”点击Sprite Collection,创建一个Sprite Collecti ...

  6. Clion调试ROS包

    1. 安装 从官网下载最新版本的Clion https://www.jetbrains.com/clion/ 并解压到指定的目录,例如: /home/xkc/software/clion-2017.2 ...

  7. ORACLE中的字符串替换 replce、regexp_replace 和 translate

    一.语法 replace(str_source,str1,str2)  把 str_source 中 str1 字符串替换为 str2 字符串,当 str2 为 null 或'' 时,与下个作用相同 ...

  8. float:浮点型double:双精度实型decimal:数字型单精度浮点数(Single)双精度浮点数(double)

        单精度浮点数(Single) 双精度浮点数(double)       Decimal为SQL Server.MySql等数据库的一种数据类型,不属于浮点数类型,可以在定义时划定整数部分以及小 ...

  9. C++ - 定义无双引号的字符串宏

    在某些特殊场合下,我们可能需要定义一个字符串宏,但又不能用双引号 比如像这样 #define HELLO hello world 如果我们只是简单的展开HELLO,肯定会无法编译 std::cout ...

  10. java类型生命周期

    开始阶段 装载:把二进制形式的java类型读入jvm中. 1)通过该类型的完全限定名,产生一个代表该类型的二进制数据流:2)解析这个二进制数据流为方法区内的内部数据结构:3)创建一个表示该类型的jav ...