《Learning Spark》这本书算是Spark入门的必读书了,中文版是《Spark快速大数据分析》,不过豆瓣书评很有意思的是,英文原版评分7.4,评论都说入门而已深入不足,中文译版评分8.4,评论一片好评,有点意思。我倒觉得这本书可以作为官方文档的一个补充,刷完后基本上对Spark的一些基本概念、码简单的程序是没有问题的了。这本书有一个好处是它是用三门语言写的,Python/Java/Scala,所以适用性很广,我的观点是,先精通一门语言,再去学其他语言。由于我工作中比较常用的是Python,所以就用把Python相关的命令总结一下。下一阶段再深入学习Java和Scala。这一篇总结第一章-第三章的重点内容。

说到Spark,就不得不提到RDD,RDD,字面意思是弹性分布式数据集,其实就是分布式的元素集合。Python的基本内置的数据类型有整型、字符串、元祖、列表、字典,布尔类型等,而Spark的数据类型只有RDD这一种,在Spark里,对数据的所有操作,基本上就是围绕RDD来的,譬如创建、转换、求值等等。所有RDD的转换都是lazy(惰性求值)的,RDD的转换操作会生成新的RDD,新的RDD的数据依赖于原来的RDD的数据,每个RDD又包含多个分区。那么一段程序实际上就构造了一个由相互依赖的多个RDD组成的有向无环图(DAG)。并通过在RDD上执行动作将这个有向无环图作为一个Job提交给Spark执行。理解RDD后可以避免以后走很多弯路。关于RDD的特点,可以搜到很多资料,其实我们只需要理解两点就可以了:

1.不可变

2.分布式

有人会觉得很奇怪,如果RDD不可变,那么在进行数据操作的时候,怎么改变它的值,怎么进行计算呢?其实RDD支持两种操作:

1.Tansformation(转化操作):返回值还是一个RDD

2.Action(行动操作):返回值不是一个RDD

第一种Transformation是返回一个新的RDD,如map(),filter()等。这种操作是lazy(惰性)的,即从一个RDD转换生成另一个RDD的操作不是马上执行,只是记录下来,只有等到有Action操作是才会真正启动计算,将生成的新RDD写到内存或hdfs里,不会对原有的RDD的值进行改变。而Action操作才会实际触发Spark计算,对RDD计算出一个结果,并把结果返回到内存或hdfs中,如count(),first()等。

通俗点理解的话,就是假设你写了一堆程序,里面对数据进行了多次转换,这个时候实际上没有计算,就只是放着这里。在最后出结果的时候会用到Action操作,这个时候Action会执行与之相关的转换操作,运算速度会非常快(一是Action不一定需要调用所有的transformation操作,二是只有在最后一步才会计算相关的transformation操作)。如果Transformation没有lazy性质的话,每转换一次就要计算一次,最后Action操作的时候还要计算一次,会非常耗内存,也会极大降低计算速度。

还有一种情况,如果我们想多次使用同一个RDD,每次都对RDD进行Action操作的话,会极大的消耗Spark的内存,这种情况下,我们可以使用RDD.persist()把这个RDD缓存下来,在内存不足时,可以存储到磁盘(disk)里。在Python中,储存的对象永远是通过Pickle库序列化过的,所以社不设置序列化级别不会产生影响。

RDD的性质和操作方式讲完了,现在来说说怎么创建RDD,有两种方式

1.读取一个外部数据集

2.在内存中对一个集合进行并行化(parallelize)

第二种方式相对来说更简单,你可以直接在shell里快速创建RDD,举个例子:

1 A = [1,2,3,4,5]

2 lines = sc.parallelize(A)

3 #另一种方式

4 lines = sc.parallelize([1,2,3,4,5])

但是这种方式并不是很好,因为你需要把你的整个数据集放在内存里,如果数据量比较大,会很占内存。所以,可以在测试的时候用这种方式,简单快速。

读取外部数据及时需要用到SparkContext.textFile()

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

RDD的操作命令很多,包括map(),filter()等Transformation操作以及reduce(),fold(),aggregate()等Action操作。

常见的Transformation操作:

map( )和flatMap( )的联系和区别

map( ):接收一个函数,应用到RDD中的每个元素,然后为每一条输入返回一个对象。

filter( ):接收一个函数,将函数的元素放入新的RDD中返回。

flatMap( ):接收一个函数,应用到RDD中的每个元素,返回一个包含可迭代的类型(如list等)的RDD,可以理解为先Map(),后flat().

用一个图可以很清楚的理解:

伪集合操作:

1 distinct( )、union( )、intersection( )、subtract( )

2 distinct( ):去重

3 union( ):两个RDD的并集

4 intersection( ):两个RDD的交集

5 subtract( ):两个RDD的补集

6 cartesian( ):两个RDD的笛卡尔积(可以应用于计算相似度中,如计算各用户对各种产品的预期兴趣程度)

注:

1.intersection( )的性能比union( )差很多,因为它需要数据混洗来发现共同数据

2.substract( )也需要数据混洗

常见的Action操作:

1 reduce( ):接收一个函数作为参数,这个函数要操作两个相同元素类型的RDD,也返回一个同样类型的RDD,可以计算RDD中元素的和、个数、以及其他聚合类型的操作。

2

3 fold( ):和reduce一样,但需要提供初始值。

4

5 aggregate( ):和fold类似,但通常返回不同类型的函数。

6

7 注:

关于fold()和aggregate(),再说点题外话。fold()只能做同构聚合操作,就是说,如果你有一个RDD[X],通过fold,你只能构造出一个X。但是如果你想通过RDD[X]构造一个Y呢?那就得用到aggregate()了,使用aggregate时,需要提供初始值(初始值的类型与最终返回的类型相同),然后通过一个函数把一RDD的元素合并起来放到累加器里,再提供一个函数将累加器两两相加。由此可以看出,fold()需要保证灭个partition能够独立进行运算,而aggregate()对于不同partition(分区)提交的最终结果专门定义了一个函数来进行处理。

RDD还有很多其他的操作命令,譬如collect(),count(),take(),top(),countByValue(),foreach()等,限于篇幅,就不一一表述了。

最后来讲讲如何向Spark传递函数:

两种方式:

1.简单的函数:lambda表达式。

适合比较短的函数,不支持多语句函数和无返回值的语句。

2.def函数

会将整个对象传递过去,但是最好不要传递一个带字段引用的函数。如果你传递的对象是某个对象的成员,或者在某个函数中引用了一个整个字段,会报错。举个例子:

1 class MyClass(object):

2 def __init__(self):

3 self.field = “Hello”

4

5 def doStuff(self, rdd):

6 #报错:因为在self.field中引用了整个self

7 return rdd.map(lambda s: self.field + x)

解决方法:直接把你需要的字段拿出来放到一个局部变量里,然后传递这个局部变量就可以了。

1 class MyClass(object):

2 def __init__(self):

3 self.field = “Hello”

4

5 def doStuff(self, rdd):

6 #将需要的字段提取到局部变量中即可

7 field = self.field

8 return rdd.map(lambda s: field + x)

前面三章讲了Spark的基本概念和RDD的特性以及一些简单的命令,比较简单。后面三章主要讲了键值对操作、数据的读取和保存以及累加器、广播变量等,下周再更新。

原文转自:http://www.cnblogs.com/charlotte77/p/5412709.html

pythonsparkpickle_Learning Spark (Python版) 学习笔记(一)----RDD 基本概念与命令相关推荐

  1. 林子雨-Spark入门教程(Python版)-学习笔记(二)

    第3章 Spark编程基础 从文件加载数据 从文件系统中加载数据创建RDD--textFile()方法,该方法把文件的URI作为参数 注意: (1)本地文件系统的路径,必须要保证在所有的worker节 ...

  2. 林子雨-Spark入门教程(Python版)-学习笔记(一)

    第1章 Spark的设计与运行原理 简介 hadoop中计算框架MapReduce的缺点: 表能能力有限,计算都必须要转化成Map和Reduce两个操作,难以表示复杂场景 IO开销大,中间结果写入到磁 ...

  3. 1算法分析——数据结构与算法Python版学习笔记

    什么是算法分析? 计算资源指标:一种是算法解决问题过程中需要的储存空间或内存,另一种是算法的执行时间 运行时间检测 time模块,获取计算机系统当前时间 例如: 方法一:累计求和程序的运行时间检测 i ...

  4. Opencv Python版学习笔记01.计算机眼中的图像

    在计算机眼里,图像是通过数字矩阵的形式存储的.如上图所示,这张图片被分为了若干个小方格,但是每个方格仍然不够小,随意取出一个方格放大观察,这个方格是由许多小格组成的,其中每个小格叫做一个像素点,像素点 ...

  5. 36篇博文带你学完opencv :python+opencv进阶版学习笔记目录

    基础版学习笔记传送门 36篇博文带你学完opencv :python3+opencv学习笔记汇总目录(基础版) 进阶版笔记 项目 opencv进阶学习笔记1: 调用摄像头用法大全(打开摄像头,打开摄像 ...

  6. 《Python编程:从入门到实战》(第2版)学习笔记 第5章 if语句

    [写在前面]为进一步提高自己的python代码能力,打算把几本经典书籍重新过一遍,形成系统的知识体系,同时适当记录一些学习笔记,我尽量及时更新!先从经典的<Python编程:从入门到实战> ...

  7. 笨办法学python第五版_最新《笨办法学python》学习笔记

    <笨办法学 python >学习笔记( Python 3.6 ) 习题 19 ex19.py # -*- coding: utf-8 -*- # 定义 cheese_and_cracker ...

  8. Python数据结构学习笔记——链表:无序链表和有序链表

    目录 一.链表 二.无序链表 实现步骤分析 三.无序链表的Python实现代码 四.有序链表 实现步骤分析 五.有序链表的Python实现代码 结语 一.链表 链表中每一个元素都由为两部分构成:一是该 ...

  9. Python数据结构学习笔记——队列和双端队列

    目录 一.队列的定义 二.队列 实现步骤分析 三.队列的Python实现代码 四.队列的应用 六人传土豆游戏 五.双端队列的定义 六.双端队列 实现步骤分析 七.双端队列的Python实现代码 八.双 ...

最新文章

  1. div块内的CSS中心文本(水平和垂直)
  2. ITK:图像重新取样
  3. dataguard如何实现切换_深度干货 | 如何借助云原生搞定Oracle备份快速恢复?
  4. Grand Central Dispatch(GCD)
  5. 曲线 神经网络_神经网络的数学基础-8(完结)
  6. 实现一个简单的HTTP
  7. css的position属性取值
  8. 编译OpenJDK8:OpenJDK8与OpenJDK8u运行结果相差很大
  9. 哔哩哔哩视频下载助手
  10. android 中通过SimpleDateFormat自定义显示英文的时间格式
  11. 基于Unity3d的FPS与塔防相结合的游戏设计
  12. 前复权 后复权和不复权是什么意思
  13. S3C2440 蜂鸣器 汇编语言,S3C2440的基础功能模块实现过程
  14. 零伽壹浅谈:区块链技术在审计工作的应用
  15. macbook录屏声音收录的处理
  16. FPGA基础设计(10)Verilog行为级建模(过程赋值)
  17. 镜子中的 Google
  18. WEB开发碰到的问题及经验十八则
  19. pythonturtle写字_python用turtle写字
  20. 修改Chromium源码实现HEVC/H.265 4K视频播放

热门文章

  1. 判断数组中有该元素?
  2. Ionic实战 自动升级APP(Android版)
  3. 关于Linux和Windows双系统共存时间问题
  4. 不要让中国孩子买的玩具都变成外国货!
  5. 九维 Addon for SBO 功能说明及新版软件下载
  6. Asp.NET 的几个高级技巧
  7. 第44节:Java当中的JVM
  8. 【转】Impala导出查询结果到文件
  9. (19)C++项目练习二----------【音乐播放器】
  10. nmake构建Geos库