SPark学习笔记:05-SPark RDD的持久化

文章目录

  • RDD的持久化
    • checkpoint()
      • checkpoint的使用
      • checkpoint的流程:
    • cache()/persist()
      • persist的使用
      • persist的持久化级别
    • checkpoint和persist(数据缓存磁盘方式)的区别

RDD的持久化

RDD的持久化是Spark中的一个非常重要的概念。当我们持久化一个RDD时,每个节点将其所计算的每个分区持久化到内存中,这样用到这些数据的其他的行动算子就可以复用这一部分数据。(通常会比不持久化的速度快10倍)
RDD有两种持久化方式

  • checkpoint
  • cache/persist

checkpoint()

checkpoint(快照),是spark中提供的另一個持久化的重要功能。因为有时候我们的Spark应用比较复杂,从初始化RDD开始,有很长一串的转换处理,且整个应用运行的时间可能也非常长。对于这类复杂的Spark任务,有很高的风险会出现某个要反复使用的RDD因为节点的故障导致数据丢失,如果失败的时候没有容错机制,当后面的Transformations算子又需要用到这个RDD时发现数据丢失,那么有需要从头到尾重新计算一次,直到该RDD算出结果。所以针对这类任务,如果我们担心某些关键的,后续反复使用的RDD因节点故障导致数据丢失,就可以针对该RDD做一个checkpoint,实现容错和高可用。

checkpoint的使用

import org.apache.spark.{SparkConf, SparkContext}

object Persistence {
  def main(args: Array[String]): Unit = {
    val conf:SparkConf = new SparkConf()
    conf.setMaster("local").setAppName("persistenceTest")

    //2.创建sc
    val sc:SparkContext = new SparkContext(conf)

    //3.创建RDD
    val inputPath:String = "D:\\javaworkspace\\BigData\\Spark\\SparkApp\\src\\main\\resources\\sensor.txt"
    val rdd2 = sc.textFile(inputPath)
      .filter(_.nonEmpty)
      .map(data=>{
        val arr = data.split(",")
        SensorReading(arr(0),arr(1).toLong,arr(2).toDouble)
      })
    rdd2.cache()
    sc.setCheckpointDir("./checkpoint")
    rdd2.checkpoint()
    rdd2.foreach(print)
    sc.stop()
  }
}

Tips:checkpoint()也只懒执行的,需要Action算子触发。

checkpoint的流程:

  1. sparkContext设置checkpoint目录,用于存放checkpoint的数据,对RDD调用checkpoint时,该RDD就会被RDDCheckpointData对象进行管理,此时RDD的checkpoint状态会被设置为Initialized.

  2. 待RDD所在的job运行结束后,会调用job中最后一个RDD的doCheckpoint方法,该方法沿着RDD的依赖关系向上查找被checkpoint标记过的RDD,并将其checkpoint状态设置为CheckpointingInProgress

  3. 启动一个单独的job,来将有依赖关系中被标记为CheckpointingInProgress的RDD执行checkpoint操作,将数据序列化后写入到checkpoint目录中。

  4. 将RDD数据写入到checkpoint目录后,会将RDD状态变为Checkpointed,并且还会改变RDD的依赖关系,会清除掉其所有依赖的RDD,并设置其父RDD为保存的checkpointRDD。

一般checkpoint都是和cache或者persist结合使用的,为什么要这样使用呢?

:我们知道RDD是不存储数据的,由上面的流程我们知道,在Action算子触发执行完毕后启动单独的job来执行将RDD的数据写入到checkpoint目录中,这时RDD的计算已经完成,RDD中没有存储数据,就需要重新从头开始计算得出RDD的数据,再写入到checkpoint目录中,效率会比较低,所以推荐和cache或者persist一起使用,这样就不需要重新计算RDD的数据。

cache()/persist()

cache()将RDD持久化到内存中,查看spark源码,cache就是由persist()实现的。

persist的使用

import org.apache.spark.storage.StorageLevel
import org.apache.spark.{SparkConf, SparkContext}

object Persistence {
  def main(args: Array[String]): Unit = {
    val conf:SparkConf = new SparkConf()
    conf.setMaster("local").setAppName("persistenceTest")

    //2.创建sc
    val sc:SparkContext = new SparkContext(conf)

    //3.创建RDD
    val inputPath:String = "D:\\javaworkspace\\BigData\\Spark\\SparkApp\\src\\main\\resources\\sensor.txt"
    val rdd2 = sc.textFile(inputPath)
      .filter(_.nonEmpty)
      .map(data=>{
        val arr = data.split(",")
        SensorReading(arr(0),arr(1).toLong,arr(2).toDouble)
      })
    val rdd3 = rdd2.map(data=>{data})
    
    //rdd3.cache()
    
    rdd3.persist(StorageLevel.MEMORY_ONLY)
    
    val start:Long = System.currentTimeMillis()
    rdd3.count()
    val end:Long = System.currentTimeMillis()
    println("==========================firtsttime:"+(end-start))

    rdd3.count()
    val start2:Long = System.currentTimeMillis()
    println("==========================secondtime:"+(start2-end))

    sc.stop()
  }
}

persist的持久化级别

@DeveloperApi
class StorageLevel private(
    private var _useDisk: Boolean,
    private var _useMemory: Boolean,
    private var _useOffHeap: Boolean,
    private var _deserialized: Boolean,
    private var _replication: Int = 1)
  extends Externalizable 
StorageLevel {
val NONE = new StorageLevel(false, false, false, false)
val DISK_ONLY = new StorageLevel(true, false, false, false)
val DISK_ONLY_2 = new StorageLevel(true, false, false, false, 2)
val DISK_ONLY_3 = new StorageLevel(true, false, false, false, 3)
val MEMORY_ONLY = new StorageLevel(false, true, false, true)
val MEMORY_ONLY_2 = new StorageLevel(false, true, false, true, 2)
val MEMORY_ONLY_SER = new StorageLevel(false, true, false, false)
val MEMORY_ONLY_SER_2 = new StorageLevel(false, true, false, false, 2)
val MEMORY_AND_DISK = new StorageLevel(true, true, false, true)
val MEMORY_AND_DISK_2 = new StorageLevel(true, true, false, true, 2)
val MEMORY_AND_DISK_SER = new StorageLevel(true, true, false, false)
val MEMORY_AND_DISK_SER_2 = new StorageLevel(true, true, false, false, 2)
val OFF_HEAP = new StorageLevel(true, true, true, false, 1)
持久化级别 说明
MEMORY_ONLY 仅存在内存中
MEMORY_AND_DISK 存储在内存和磁盘中
MEMORY_ONLY_SER 存储在内存中并序列化
MEMORY_AND_DISK_SER 存储在内存中和磁盘中并序列化
DISK_ONLY 仅存储在磁盘中
MEMORY_ONLY_2 存储在内存中,并设置1个副本
MEMORY_AND_DISK_2 存储在内存和磁盘中,并设置1个副本
OFF_HEAP 存储在磁盘中,内存中并使用堆内存

checkpoint和persist(数据缓存磁盘方式)的区别

  • checkpoint斩断了RDD与父RDD的依赖关系,而persist则保存了RDD与父RDD的一条依赖链,当persist的数据丢失时会重新计算得到RDD的数据;二checkpoint则可以通过HDFS的文件副本的方式保证数据的安全性。
  • persist一旦程序运行结束,缓存在磁盘中的文件就会被删掉,而checkpoint的文件则不会被删掉,可以被下一个driver或application使用,而persist的文件不能被其他程序使用。

你可能感兴趣的:(Spark,大数据,spark,学习,大数据)