大数据组件-什么是RDD,saprkRDD分区和Shuffle,缓存,Checkpoint

什么是RDD

当有多台电脑,多台电脑上的分布着不同的数据,我们使用RDD来统一这些数据命名,故而RDD就是分布式数据集.
当有了整个在多台计算机分布的大型数组RDD,我们才可以通过一系列算子对其进行操作

RDD分区以及Shuffle操作

  1. RDD分区是一个并行计算实现的手段

1.查看分区的手段

(1)使用partitions查看

rdd.partitions.size

(2)使用webUI页面查看

node01:4040

在这里插入图片描述

2.通过算子指定分区数

一般情况下涉及Shuffle的操作的算子都可以指定分区数,在最后一位参数指定分区数,如果没有指定默认从父RDD中继承分区数

3.Spark 中的 Shuffle 操作的特点

  • 只有 Key-Value 型的 RDD 才会有 Shuffle 操作, 例如 RDD[(K, V)], 但是有一个特例, 就是 repartition 算子可以对任何数据类型 Shuffle

RDD的缓存

1.RDD缓存作用

缓存能够帮助开发者在进行一些昂贵操作后, 将其结果保存下来, 以便下次使用无需再次执行, 缓存能够显著的提升性能.

2.RDD缓存API

转换算子的作用:生成RDD,以及RDD之间的依赖关系
Action算子的作用:生成job,去执行job,有一个job,RDD就要执行一次
我们使用缓存的意义就是减少shuffle,缓存其他算子生成的结果

(1)cahe缓存

可以使用 cache 方法进行缓存

val conf = new SparkConf().setMaster("local[6]").setAppName("debug_string")
val sc = new SparkContext(conf)

val interimRDD = sc.textFile("dataset/access_log_sample.txt")
  .map(item => (item.split(" ")(0), 1))
  .filter(item => StringUtils.isNotBlank(item._1))
  .reduceByKey((curr, agg) => curr + agg)
  .cache() //缓存rdd

val resultLess = interimRDD.sortBy(item => item._2, ascending = true).first()
val resultMore = interimRDD.sortBy(item => item._2, ascending = false).first()

println(s"出现次数最少的 IP : $resultLess, 出现次数最多的 IP : $resultMore")

sc.stop()

(2)persist(可以指定缓存级别的缓存)

al conf = new SparkConf().setMaster("local[6]").setAppName("debug_string")
val sc = new SparkContext(conf)

val interimRDD = sc.textFile("dataset/access_log_sample.txt")
  .map(item => (item.split(" ")(0), 1))
  .filter(item => StringUtils.isNotBlank(item._1))
  .reduceByKey((curr, agg) => curr + agg)
  .persist(StorageLevel.MEMORY_ONLY) 

val resultLess = interimRDD.sortBy(item => item._2, ascending = true).first()
val resultMore = interimRDD.sortBy(item => item._2, ascending = false).first()

println(s"出现次数最少的 IP : $resultLess, 出现次数最多的 IP : $resultMore")

sc.stop()

persist() 是 persist(newLevel: StorageLevel) 的一个别名, persist(newLevel: StorageLevel) 能够指定缓存的级别

3.缓存级别设置

是否使用磁盘缓存?
是否使用内存缓存?
是否使用堆外内存?
缓存前是否先序列化?
是否需要有副本?

在这里插入代码片

是否反序列化形式存储,如果是false是二进制数据,如果是true存的是对象
在这里插入图片描述在这里插入图片描述

4.缓存级别选择

  • Spark 的存储级别的选择,核心问题是在 memory 内存使用率和 CPU 效率之间进行权衡。建议按下面的过程进行存储级别的选择:
  • 一般使用RDD 默认存储级别MEMORY_ONLY。这是 CPU 效率最高的选项,因为没有序列化这个过程,允许 RDD 上的操作尽可能快地运行.
  • MEMORY_ONLY_SER 他使用了序列化 数据变为二进制保存更加节省空间,但仍然能够快速访问。(Java和Scala)
  • 不要溢出到磁盘,除非计算您的数据集的函数是昂贵的.溢写效率比较低
  • 如果需要快速故障恢复,请使用复制的存储级别(末尾加2)。复制的数据可让您你继续在 RDD 上运行任务,而无需等待重新计算一个丢失的分区.

RDD的Checkpoint

1.Checkpoint使用场景

就是可以将迭代多次RDD存储在HDFS上
Checkpoint 的主要作用是斩断 RDD 的依赖链, 并且将数据存储在可靠的存储引擎中, 例如支持分布式存储和副本机制的 HDFS.

2.Checkpoint 和 Cache 的区别

他们的区别主要在以下两点

  • Checkpoint 可以保存数据到 HDFS 这类可靠的存储上, Persist 和 Cache 只能保存在本地的磁盘和内存中
  • Checkpoint 可以斩断 RDD 的依赖链, 而 Persist 和 Cache 不行
  • 因为 CheckpointRDD 没有向上的依赖链, 所以程序结束后依然存在, 不会被删除. 而 Cache 和 Persist 会在程序结束后立刻被清除.

3.使用 Checkpoint

val conf = new SparkConf().setMaster("local[6]").setAppName("debug_string")
val sc = new SparkContext(conf)
//设置保存Checkpoint目录,也可以设置hdfs上目录
sc.setCheckpointDir("checkpoint") 

val interimRDD = sc.textFile("dataset/access_log_sample.txt")
  .map(item => (item.split(" ")(0), 1))
  .filter(item => StringUtils.isNotBlank(item._1))
  .reduceByKey((curr, agg) => curr + agg)

interimRDD.checkpoint() //

interimRDD.collect().foreach(println(_))

sc.stop()

在使用 Checkpoint 之前需要先设置 Checkpoint 的存储路径, 而且如果任务在集群中运行的话, 这个路径必须是 HDFS 上的路径
开启 Checkpoint

val interimRDD = sc.textFile("dataset/access_log_sample.txt")
  .map(item => (item.split(" ")(0), 1))
  .filter(item => StringUtils.isNotBlank(item._1))
  .reduceByKey((curr, agg) => curr + agg)
  .cache()  //在Checkpoint之前先cache缓存一下

interimRDD.checkpoint()
interimRDD.collect().foreach(println(_))

checkpoint 之前先 cache 一下, 因为 checkpoint 会重新计算整个 RDD 的数据然后再存入 HDFS 等地方.
所以上述代码中如果 checkpoint 之前没有 cache, 则整个流程会被计算两次, 一次是 checkpoint, 另外一次是 collect

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章