Spark RDD概述

一.RDD的概述

1.1. 什么是RDD
RDD(Resilient Distributed Dataset)叫做弹性分布式数据集,是Spark中最基本的数据抽象,它代表一个不可变、可分区、里面的元素可并行计算的集合。RDD具有数据流模型的特点:自动容错、位置感知性调度和可伸缩性。RDD允许用户在执行多个查询时显式地将工作集缓存在内存中,避免了如mapreduce许多重复的落地写磁盘操作,也避免了网络间传输数据时过多的序列化与反序列化操作开销,后续的查询能够重用工作集,这极大地提升了查询速度。
1.2. RDD的特性

  • RDD是由一系列的partition组成
  • 高效的容错性
  • 算子是作用在partition上的
  • RDD之间有依赖关系
  • 分区器是作用在k,v格式的RDD上
  • partition对外提供最佳的计算位置

问题:
1.什么是k,v格式的RDD?
RDD中的每个元素是一个二元组,那么这个RDD就是k,v格式的RDD,这种类型的RDD是根据哈希来分区的,类似于mapreduce当中的partition接口。
2.spark中能直接读取HDFS中文件吗?
spark中没有能直接读取HDFS中文件的方法,比如sc.textFile()调用的是MR来读取,首先会split,就是一个block,每个block对应RDD中的一个partition。
3.哪里体现了RDD的弹性?

  • RDD的partition个数可多可少
  • RDD之间有依赖关系

4.哪里体现了RDD的分布式?
RDD的分区分布在多个节点上。
5.如何理解高效的容错性?
RDD血缘关系、重新计算丢失分区、无需回滚系统、重算过程在不同节点之间并行、只记录粗粒度的操作
1.3. wordcount图解RDD
在这里插入图片描述
其中hello.txt
在这里插入图片描述

二.RDD宽依赖与窄依赖

2.1 RDD依赖关系的本质内幕
由于RDD是粗粒度的操作数据集,每个Transformation操作都会生成一个新的RDD,所以RDD之间就会形成类似流水线的前后依赖关系;RDD和它依赖的父RDD(s)的关系有两种不同的类型,即窄依赖(narrow dependency)和宽依赖(wide dependency)。如图所示显示了RDD之间的依赖关系。
在这里插入图片描述
从图中可知:
窄依赖:是指每个父RDD的一个Partition最多被子RDD的一个Partition所使用,例如map、filter、union等操作都会产生窄依赖;(独生子女)
宽依赖:是指一个父RDD的Partition会被多个子RDD的Partition所使用,例如groupByKey、reduceByKey、sortByKey等操作都会产生宽依赖;(超生)
2.2 依赖关系下的数据流视图
spark之所以将依赖分为narrow与shuffle,基于两点原因:
首先,narrow dependencies可以支持在同一个cluster node上以pipeline的形式执行多条命令,例如在执行了map后,紧接着执行filter。相反shuffle dependencies需要所有的父分区都是可用的。
其次,则是从失败回复的角度考虑。窄依赖的失败恢复更有效,因为它只需从新计算父分区即可,而且可以并行在不同节点进行重计算。而宽依赖牵涉RDD各级的多个父分区。
如下图所示:
![在这里插入图片描述](https://img-blog.csdnimg.cn/2019011520262815.jpg?x-oss-process=image/watermark,type_Z

三.RDD中算子(这里只作简要概述)

3.1 什么是算子
算子是RDD中定义的函数,可以对RDD中的数据进行转换和操作。
算子分类:

  • Transformation(转换)
  • Action(执行)
    作用:
  • transformation是得到一个新的RDD,方式很多,比如从数据源生成一个新的RDD,从RDD生成一个新的RDD,Transformation属于延迟计算,当一个RDD转换成另一个RDD时并没有立即进行转换,仅仅是记住了数据集的逻辑操作。
  • action是得到一个值,或者一个结果(直接将RDDcache到内存中),触发Spark作业的运行,真正触发转换算子的计算。
    所有的transformation都是采用的懒策略,如果只是将transformation提交是不会执行计算的,计算只有在action被提交的时候才被触发。
    在这里插入图片描述

3.2 实例操作
以下实例用来验证action和transformation之间区别与联系(RDD.cache()也属于懒执行持久化算子):

package cn.itcast.demo
import org.apache.spark.{SparkConf, SparkContext}
class testdemo {
}
object testdemo {
  /*
   *持久化算子
  cache默认将数据存在内存中,懒执行算子
   */
  def main(args: Array[String]): Unit = {
    val conf = new SparkConf().setMaster("local").setAppName("cacheTest")
    val sc = new SparkContext(conf)
    val RDD = sc.textFile("datademo.txt")
    RDD.cache()
    val starttime = System.currentTimeMillis()
    val count1 = RDD.count()
    val endtime = System.currentTimeMillis()
    println("count1前后时间差为:" + (endtime - starttime))

    val starttime1 = System.currentTimeMillis()
    val count2 = RDD.count()
    val endtime1 = System.currentTimeMillis()
    println("count2前后时间差为:" + (endtime1 - starttime1))
    /*
    在这里,count1肯定是从磁盘读取数据,因为RDD不存数据
    RDD.cache()也并没有将数据放在内存中(懒执行)
    接下来count()也就不能从内存中读取数据,但作为action它会触发持久化算子
    也就是cache,于是再接下来的count2就能得到被cache保存在内存中的数据了
     */
    sc.stop()

  }
}

在这里插入图片描述

参考:http://www.cnblogs.com/qingyunzong/p/8899715.html
https://www.cnblogs.com/LgyBean/p/6251359.html
图1~4来源:http://www.cnblogs.com/qingyunzong/p/8899715.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值