这一篇博文是【大数据技术●降龙十八掌】系列文章的其中一篇,点击查看目录:大数据技术●降龙十八掌
-
系列文章:
-
【十八掌●武功篇】第十六掌:Spark之Scala安装和HelloWorld
【十八掌●武功篇】第十六掌:Spark之Scala语法快速概览
【十八掌●武功篇】第十六掌:Spark之简介、安装、Demo
【十八掌●武功篇】第十六掌:Spark之RDD简介
一、 定义
1、 RDD定义
RDD是弹性分布式数据集(Resilient Distributed Dataset)的简称,其实就是分布式元素集合。在Spark中,对数据的所有操作不外乎创建RDD、转化已有的RDD、调用RDD操作进行求值。
2、 操作类型
RDD有两种类型的操作:Transformation操作、Action操作,Transformation操作和Action操作区别在于Spark计算RDD的方式不同。
- Transformation操作会由一个RDD生成另一个新的RDD,生成的新的RDD是惰性求值的,只有在Action操作时才会被计算。
- Action操作会对RDD计算出一个结果,并把结果返回到驱动器程序中,或者是把结果存储到外部存储系统中。
二、 Spark RDD五大特性
RDD是弹性分布式数据集,是Spark中最关键、最基本的一个抽象,他代表的是不可变的、分区的集合,这个集合可以被并行处理。
Internally, each RDD is characterized by five main properties:
- A list of partitions
- A function for computing each split
- A list of dependencies on other RDDs
- Optionally, a Partitioner for key-value RDDs (e.g. to say that the RDD is hash-partitioned)
- Optionally, a list of preferred locations to compute each split on (e.g. block locations for
an HDFS file)
1、 RDD是分区的
一个RDD对应的数据集合是分区的,各个分区分布在各个机器当中,每个RDD是不可变的,每个分区对应一个Task。
查看rdd的分区数量:
scala> val rdd=sc.textFile("/input.txt")
scala> rdd.getNumPartitions
16/10/18 05:16:24 INFO mapred.FileInputFormat: Total input paths to process : 1
res2: Int = 2
2、 每个分区都可以运用函数
每个分区上都应用于一个函数,各个分区运行的计算逻辑是一样的,只是数据不同。
3、 每个RDD都有一系列其他依赖
每个RDD依赖于一系列的RDD,因为有DAG,所以能找到依赖的RDD,目的是可以进行容错,当某一个RDD操作失败了,可以找到他的依赖进行重新计算。
查看某一个rdd的血缘关系:
scala> val rdd=sc.textFile("/input.txt")
scala> var wordcountRdd=rdd.flatMap(line => line.split(" ")).map(word =>(word,1)).reduceByKey((a,b)=>(a+b))
scala> wordcountRdd.toDebugString
res3: String =
(2) ShuffledRDD[4] at reduceByKey at <console>:29 []
+-(2) MapPartitionsRDD[3] at map at <console>:29 []
| MapPartitionsRDD[2] at flatMap at <console>:29 []
| /input.txt MapPartitionsRDD[1] at textFile at <console>:27 []
| /input.txt HadoopRDD[0] at textFile at <console>:27 []
4、 键值对RDD类型可以指定分区方式
对于键值对类型的RDD,可以制定一个分区方式。
5、 数据本地化
Task所运行的机器与处理的数据在同一个机器上,就是数据本地化。
三、 RDD创建方式
1、 并行化集合
scala> val list=List(1,2,3,4,5,6,7)
scala> val rddNum=sc.parallelize(list)
scala> rddNum.count
res0: Long = 7
2、 从外部数据集读取
可以从HDFS读取文件加载数据或者HBbase加载数据。
scala> val rdd=sc.textFile("/input.txt")
res1: Long = 5
四、 RDD三大Operation
1、 transformation(转换)
从一个RDD变为另外一个RDD的操作叫做transformation操作,transformation的操作都是懒操作,即不会立即执行,只有当进行action操作时才会真正的去执行。
如:map()、filter()、distinct()
2、 action(执行)
action操作能返回Driver程序一个值或者是导出数据到外部系统。
比如:count()、reduce()、collect()、take()
3、 Persistence(持久化)
缓存数据到内存、磁盘、外部的存储器。
persist():缓存数据,可以指定缓存级别。
cache():就是调用的persist(),缓存级别为内存。
(1) 缓存级别:
- NONE:都不存储
- DISK_ONLY:只存储在磁盘
- DISK_ONLY_2:只存储在磁盘,存储两个副本
- MEMORY_ONLY:只存放内存中
- MEMORY_ONLY_2:只存放在内存中,存储两个副本。
- MEMORY_ONLY_SER:只存储在内存中并序列化到磁盘
- MEMORY_ONLY_SER_2:只存储在内存中并序列化到磁盘,存储两个副本
- MEMORY_AND_DISK:优先放入内存,内存不够就放在硬盘
- MEMORY_AND_DISK_2:优先放入内存,内存不够就放在硬盘,存储两个副本
- MEMORY_AND_DISK_SER:优先放入内存,内存不够就放在硬盘,并序列化
- MEMORY_AND_DISK_SER_2:优先放入内存,内存不够就放在硬盘,并序列化,存储两个副本
- OFF_HEAP:外部存储。
(2) 何时进行缓存
有两种情况下要进行缓存:
- RDD之后会被使用很多次
- 某个RDD的数据是经过非常复杂的清洗过滤得到的