RDD基础

目录

1.RDD概念

1.1 弹性

1.2 分布式

1.3 数据集

1.4 数据抽象

1.5 不可变

1.6 可分区、并行计算

2.RDD核心属性

2.1 分区

2.2 依赖关系多个RDD之间的依赖关系。

2.3 分区器

3.执行原理

3.1 RDD在Yarn中的工作原理

4.编程实现

4.2 从外部存储(文件)创建RDD

4.3 路径的问题

4.4 从其他的RDD创建

4.5 直接创建RDD


1.RDD概念

RDD(Resilibute Distribute Dataset)弹性分布式数据集,是Spark中最基本的的数据处理模型。它是一个抽象类,代表一个弹性的、不可变的、可分区的、是一个元素可并行计算的集合。

1.1 弹性

存储的弹性:内存与磁盘自动切换;
容错的弹性:数据丢失可以自动恢复;
计算的弹性:计算出错需要重试机制;
分片的弹性:可根据需要重新分片;

1.2 分布式

数据存储在大数据集群不同的节点上。

1.3 数据集

RDD封装了计算逻辑,并不保存数据。

1.4 数据抽象

RDD是一个抽象类,需要子类具体实现

1.5 不可变

RDD封装了计算逻辑,是不可变的,想要改变只能产生新的RDD,在新的RDD里封装计算逻辑

1.6 可分区、并行计算


2.RDD核心属性

RDD有5大核心属性。

2.1 分区

RDD数据结构中存在分区列表,用于并行计算,是实现分布式计算的重要属性。
Spark在计算时,使用分区函数对每一个分区进行计算。每个分区的数据可以不同,但是计算逻辑相同。

2.2 依赖关系
多个RDD之间的依赖关系。

2.3 分区器

将数据进行分区。移动数据不如移动计算。
首选位置:判断计算哪一个节点效率最优。


3.执行原理

从计算的角度来说,数据处理需要计算资源(内存)和计算模型(逻辑)。执行时,需要将计算的资源和模型进行协调配合。

spark框架在执行时,先申请资源,然后将应用程序的数据处理逻辑分解成一个个的计算任务,然后分发到已经分配资源的计算节点上,按照指定的计算模型(逻辑)进行数据的计算,最后得到结果。

RDD是Spark框架中用于数据处理的核心模型。

3.1 RDD在Yarn中的工作原理

①首先时启动集群环境,启动了ResourceManager、NodeManager后,就有了计算资源;
②然后Spark申请资源,创建调度节点(Driver)和计算节点(Executor),调度节点(Driver)和计算节点(Executor)都是运行在NodeManager;
③Spark框架根据需求将计算逻辑根据分区划分成不同的任务((Task),然后放到任务池(TaskPool);
④调度节点(Driver)将任务根据计算节点状态发送到对应的计算节点进行计算;

从以上可以看出,RDD主要将逻辑进行封装,生成Task并发送给Executor节点进行计算。


4.编程实现

RDD创建方式分为四种
4.1 从集合(内存)中创建RDD
从集合(内存)中创建RDD,spark主要提供了两个方法:parallelize和makeRDD

object CreateRdd01 {
  def main(args: Array[String]): Unit = {
    val scf = new SparkConf().setMaster("local[*]").setAppName("RDD")
    val sc = new SparkContext(scf)

    //创建RDD

    val seq = Seq[Int](1,2,3,4,5)
    val rdd = sc.makeRDD(seq)
    //val rdd = sc.parallelize(seq)

    rdd.collect().foreach(println(_))

   sc.stop()
  }

}

4.2 从外部存储(文件)创建RDD

外部存储(文件),是有外部的数据集创建,包括:本地的文件系统、所有的Hdoop支持的数据集,比如HDFS、HBase等。

object CreateRdd02 {
  def main(args: Array[String]): Unit = {
    val scf = new SparkConf().setMaster("local").setAppName("RDD")
    val sc = new SparkContext(scf)

    //从文件中创建RDD,将文件中的数据作为处理的数据源;
    val rdd = sc.textFile("datas/4.txt")

    rdd.collect().foreach(println(_))

    sc.stop()
  }
}

4.3 路径的问题

①textFile()的路径可以是相对路径,
  val rdd = sc.textFile("datas/4.txt")
②也可以是绝对路径,

val rdd = sc.textFile("G:\MyWoekSpease\spring-web\spark\datas\4.txt")

③也可写文件所在的目录名;")
val rdd = sc.textFile("datas")
④还可以使用通配符;
val rdd = sc.textFile("datas/1*.txt")
⑤还可以是分布式存储路径

val rdd = sc.textFile("hdfs://cen128:50070/test.txt")

wholeTextFiles()以文件为单位读取数据,读取的结果是为元组,元组的第一个元素表示文件的路径,第二表示文件的内容;
val rdd = sc.wholeTextFiles("datas")

object CreateRdd03 {
  def main(args: Array[String]): Unit = {
    val scf = new SparkConf().setMaster("local[*]").setAppName("RDD")
    //配置分区数;
    scf.set("spark.default.parallelism", "3")
    val sc = new SparkContext(scf)

    //创建RDD

    /*
    makeRDD()方法的第二个参数表示分区数量,不写就是默认值:defaultParallelism(默认值),Spark默认从配置对象中获取
    参数spark.default.parallelism,如果获取不到,就使用totalCore属性,也就是当前系统的CPU核数为分区数(最大可用的)
     */
    //val rdd = sc.makeRDD(List(1,2,3,4,5,6,7),2)
    val rdd = sc.makeRDD(List(1, 2, 3, 4, 5, 6, 7))

    //将处理的数据保存成分区文件
    rdd.saveAsTextFile("output4")

    //关闭程序;
    sc.stop()
  }

}

分区文件里面的内容是怎样被分到分区里面的?
例如,List(1,2,3,4,5),指定为三个分区,那么运行后,每个分区的内容是:
分区1:1
分区2:2,3
分区3:4,5
那么为什么是这样的划为,而不是:
分区1:1,2
分区2:3
分区3:4,5
或者:
分区1:1,2
分区2:3,4
分区3:5
从源码可以得出结论;
如果有三个分区,把分区数看成是一个list(0,1,2),然后对list进行起始位置和末尾位置计算,计算的方式:

(0 until numSlices).iterator.map { i =>
val start = ((i*length)/numSlices)).ToInt
val end = ((i + 1)* length)//numSlices).ToInt
(start,end)
}

这里的i就是list的元素,numSlices是分区数。(start,end)

4.4 从其他的RDD创建

主要是通过一个RDD的运算完后,再产生新的RDD

4.5 直接创建RDD

使用new的方式直接构造RDD,一般由Spark框架自身使用。

     --------------------------------------未完待续。。。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值