Spark---RDD的简单了解
RDD简单简绍
RDD的定义
RDD,全称为Resilient Distributed Datasets,是一个容错的,并行的数据结构,可以让用户显式地将数据存储到磁盘和内存中,并能控制数据的分区.
同时, RDD还提供了一组丰富的操作来操作这些数据.在这些操作中,诸如map,flatMap, filter等转换操作实现了Monad模式,很好地契合了Scala 的集合操作.除此之外, RDD还提供了诸如join,groupBy, reduceByKey等更为方便的操作,以支持常见的数据运算.
通常来讲,针对数据处理有几种常见模型,包括: ITterative Algorithms, Relational Queries, MapReduce, Stream Processing.例如Hadoop MapReduce采用了MapReduce模型, Storm则采用了Stream Processing模型. RDD混合了这四种模型,使得Spark可以应用于各种大数据处理场景.
RDD作为数据结构,本质上是一个只读的分区记录集合.一个RDD可以包含多个分区,每个分区就是一个DataSet片段.
RDD之间可以相互依赖,如果RDD的每个分区最多只能被一个子RDD的一个分区使用,则称之为窄依赖,若被多个子RDD的分区依赖,则称之为宽依赖.不同的操作依据其特性,可能会产生不同的依赖.例如 map.操作会产生窄依赖,而join.操作则产生宽依赖.
RDD的特点
- RDD是数据集
可以看成RDD存储的是文件里的数据,所有RDD是数据集 - RDD是编程模型
RDD中有很多的方法,因此看成是一个编程模型 - RDD相互之间有依赖关系
RDD2通过RDD1的flatMap方法得出来的,RDD3是通过RDD2的map方法得出来的,可见RDD间有相互的依赖关系 - RDD是可以分区的
RDD是一个并行计算框架和分布式计算,所有她必须要有分区
RDD的创建方式
程序入口SparkContext
- SparkContext的简绍
SparkContext是spark-core的入口组件,是一个Spark程序的入口,在Spark 0.x版本就已经存在SparkContext 了,是一个元老级的API
如果把一个Spark程序分为前后端,那么服务端就是可以运行Spark程序的集群,而 Driver就是 Spark的前端,在 Driver 中SparkContext是最主要的组件,也是 Driver 在运行时首先会创建的组件,是 Driver的核心
SparkContext从提供的API来看,主要作用是连接集群,创建 RDD,累加器,广播变量等
- 创建SparkContext
val conf = new SparkConf()
.setMaster("local[6]")
.setAppName("Create_RDD")
val sc = new SparkContext(conf)
通过本地集合创建RDD
//使用Seq创建RDD并且设置俩个分区
val seq = Seq("Hello","Hi","NiHao")
val rdd1: RDD[String] = sc.parallelize(seq,2)
//使用makeRDD创建
val rdd2 = sc.makeRDD(seq,2)
//俩者的区别,makeRDD必须要指定分区数
通过外部数据创建RDD
val rdd1: RDD[String] = sc.textFile("D:\\SP\\Soft")
通过RDD来衍生RDD
val rdd1: RDD[Int] = sc.parallelize(Seq(1,2,3))
//通过RDD衍生
val rdd2: RDD[Int] = rdd1.map(item=>item)
常用的几个算子
Map算子
主要作用:将一份数据转换成另外一份数据
将value1、2、3以同一种形式转换成value’1,'2,'3
//创建RDD
val rdd1 = sc.parallelize(Seq(1,2,3))
println(rdd1.foreach(println(_)))
//执行map操作,将数据扩大10倍
val rdd2 = rdd1.map(item=>item*10)
.collect()
.foreach(println(_))
解析
flatMap算子
//创建RDD
val rdd1 = sc.parallelize(Seq("hello world","hi Jack"))
//转换,将数据以空格分割
rdd1.flatMap(_.split(" "))
.collect()
.foreach(println(_))
思考map和flatMap的区别?
答:map转换是一对一,flatMap是一对多
ReduceByKey算子
流程图
按照key进行分组,然后开始自定义的操作
//创建RDD
val rdd1 = sc.parallelize(Seq("hello world", "hi world", "hello Rom"))
//处理数据
rdd1.flatMap(_.split(" "))
.map(item => (item, 1))
.reduceByKey((curr, agg) => curr + agg)
.collect()
.foreach(println(_))
//关闭
sc.stop()