在SparkCore中的一切计算都是基于RDD的,那RDD是个什么东西呢?
RDD是Resilient Distribute Dataset(弹性分布式数据集)的缩写,说白了,RDD可以理解为spark处理数据的基本单位,但是RDD又不是真实的存有数据,它只是具有操作数据的能力,相当于一个租房中介,中介手上掌握了一手的房源信息,而sparkCore就相当于租房子的人,一般直接找到房子不简单,所以我们找到中介,中介向我们提供租房信息,我们在中介提供的信息的基础上进行价格,位置等筛选处理,就相当于spark通过RDD对源数据进行计算。好了,现在我们理解了RDD是个什么东西,现在直接上一个WordCount的scala代码分析来帮助我们更加深入地理解RDD,图片不清晰可单击放大查看高清大图:
看完了以上的WordCount源码分析后相信大家对RDD有一定的理解了,接下来介绍RDD的一些特性。RDD具有五大特性:
- A list of partitions
- A function for computing each partition
- A list of dependencies on other RDDs
- Optionally, a Partitioner for key-value RDDs
- Optionally, a list of preferred locations to compute each split on
这个是官网对于RDD的五大特性的解释,翻译过来差不多就是:
- RDD是由一系列的partition组成的
- RDD提供的每一个函数实际上是作用于每一个partition上的
- RDD具有一系列的依赖关系,依赖于其他的RDD
- 可选项,分区器是作用在KV格式的RDD上的(KV格式的的RDD:如果RDD中的数据是二元组类型的,那么我们就称这个RDD是KV格式的RDD,如上图的pairRDD和resRDD)
- 可选项,RDD会提供一系列的最佳的计算位置(RDD提供了一个方法接口,直接调用这个方法接口就能拿到RDD所有的partition的分区的位置)
对于第一个特性RDD是由一系列的partition组成的,可以参照下图:
结合WordCount实例的RDD分析:
由上图我们很容易就能看出RDD的依赖关系。RDD的依赖关系还可以用一张人类进化图表示:
进化完成的人类就相当于我们经过一系列处理得到的RDD。
综上,我们可以知道,RDD是sparkCore计算的基本核心,RDD是逻辑上的概念,本身不存储数据,但是具有操作数据的能力,partition也是一样的。
上面用到的WordCount的源码:
package com.hpe.spark
import org.apache.spark.SparkConf
import org.apache.spark.SparkContext
object WordCountSpark {
def main(args: Array[String]): Unit = {
//创建配置对象
val conf = new SparkConf()
//设置app的名称 有啥用?方便在监控页面找到
conf.setAppName("WordCount")
//设置spark的运行模式 local本地运行 用于测试环境
conf.setMaster("local")
//创建上下文 他是通往集群的唯一通道
val sc = new SparkContext(conf)
/**
* 处理数据 在sparkCore中一切计算都是基于RDD
* R(resilient)D(distribute)D(dataset)
* RDD:弹性分布式数据集
*/
val lineRDD = sc.textFile("d:/wc.txt")
//基于lineRDD中的数据,进行分词
val wordRDD = lineRDD.flatMap { _.split(" ") }
//将每一个单词基数为1 pairRDD K:word V:1
val pairRDD = wordRDD.map { x => (x,1)}
//将相同的单词分组,组内数据累加 hello:{1,1,1,1,1}
//restRDD K:word V:count
//val resRDD = pairRDD.reduceByKey((v1,v2) => v1+v2)
val resRDD = pairRDD.reduceByKey(_+_)
resRDD.foreach(println)
sc.stop()
}
}