Spark_checkpoint机制简介 :

首先明确RDD是一个分布式弹性数据集 , 但是RDD中不存数据 , 只存计算逻辑 数据地址和父RDD血缘关系等

在spark计算过程中 , 业务负责 , 计算流程DAG比较长且数据重要不可丢失 , 并且中间RDD需要多次复用或需要在其他模块中调用 , 需要使用spark_RDD的checkpoint机制 , 将中间结果RDD持久化到磁盘

理解RDD.cache()和RDD.checkpoint()的区别 : 

cache()缓存 :

适用于本次Job多次复用某个DAG链较长的中间RDD , 缓存以后不用每次都从头计算 , 二次复用会调用缓存中的RDD结果数据集 , 省去前边冗余的计算流程链 , 节省资源 , 提高效率

checkpoint() :

RDD结果数据持久化到一个高可用的位置(HDFS) , 我这里测试直接落地到本地磁盘 , 省去前边负责冗余的计算流程链 , 节省资源 , 提高效率 , 数据多次复用与其他板块

话不多说直接上代码:

将重要的中间结果RDD.checkpoint持久化数据到本地磁盘 , 如下

/**
 * Created with IntelliJ IDEA
 *
 * @Author Big_moo
 * @Date 2022/01/07/16:16
 * @Descript
 *           RDD.checkpoint
 *          将当前RDD结果数据持久化到磁盘 便于复用
 */
object checkPointRDDToDir {
  def main(args: Array[String]): Unit = {
    //创建conf对象
    val conf = new SparkConf().setAppName("checkpoint").setMaster("local[2]")
    //创建sparkContext对象
    val sparkContext = new SparkContext(conf)
    //本地集合并行化创建RDD 指定并行度(分区数)为 2
    val rdd: RDD[Int] = sparkContext.parallelize(List[Int](1, 2, 3, 4, 5, 6, 7, 8), 2)
    //假设一段超长计算流程DAG.... 得到结果数据RDD
    val resRDD: RDD[Int] = rdd.map(_ * 10).map(_ * 2).map(_ + 10).map(_ * 5).map(_ - 100)
    //resRDD 缓存 & checkpoint
    resRDD.persist(StorageLevel.MEMORY_ONLY)  //缓存级别只存于内存中
    sparkContext.setCheckpointDir("E:\\checkpoint\\out_01")  //checkpoint之前设置目的地文件夹
    resRDD.checkpoint()   //中间结果数据持久化到磁盘

    //转换算子无法触发执行 调用行动算子触发执行
    resRDD.collect()
  }
}

目标文件夹不能存在 , 运行成功后目标路径下会自动产生一个结果数据文件夹

spark删除应用 spark checkpoint多次清除_big data

需要注意的是 , checkpoint后的RDD数据已经断开了和原父RDD的血缘关系 , 成为了一个独立个体 , 重新获取成RDD也是一个全新的RDD , 不存在之前的任何计算逻辑等等

将checkpoint后的数据反向获取成一个新的RDD:

注意 : 这里有个小细节,SparkContext类中存在一个获取checkpoint持久化RDD数据的方法,但是这个方法是 protected 修饰 , 受保护的方法 , 只能在本类中调用或者同一个包下的类调用 ,这时候我们可以自己创建一个包名 org.apache.spark 这一招 [瞒天过海] 然后在这个包下写一个自己的工具类去调用这个方法, 就可以获取到 checkpoint 文件啦~~

spark删除应用 spark checkpoint多次清除_spark_02

自定义   org.apache.spark.RDDUtil

package org.apache.spark
import org.apache.spark.rdd.RDD
/**
 * Created with IntelliJ IDEA
 * @Author Big_moo
 * @Date 2022/01/07/17:25
 * @Descript
 * 自定义工具类
 */
object RDDUtil {
                                  //返回值类型记得和原checkpointRDD一致
  def getCheckPointRDD(path:String): RDD[Int] ={
    //创建sparkContext对象
    val sparkContext = new SparkContext(new SparkConf().setAppName("Get").setMaster("local[*]"))
    //同包下调用checkpointFile方法 此处默认返回值类型是 RDD[Nothing] 改成原RDD类型
    val resRDD: RDD[Int] = sparkContext.checkpointFile(path)
    //返回一个RDD
    resRDD
  }
}

反向获取checkpoint文件返回新的RDD

import org.apache.spark.RDDUtil
import org.apache.spark.rdd.RDD

/**
 * Created with IntelliJ IDEA
 * @Author Big_moo
 * @Date 2022/01/07/16:19
 * @Descript
 *
 */
object checkPointBackToRDD {
  def main(args: Array[String]): Unit = {
    //注意这里的地址要写到具体文件的上一层文件夹
    val path:String = "E:\\checkpoint\\out_01\\2198d8bd-96c9-4e7c-950c-7fe6d8d212c3\\rdd-5"
    //调用方法返回RDD
    val rdd: RDD[Int] = RDDUtil.getCheckPointRDD(path)
    //查看RDD中数据
    rdd.foreach(println)
  }
}

♥ 看完别忘点赞哦 ♥