Spark-之数据持久化(血缘关系 cache\persist\checkpoint)
- cache
- persist
- checkpoint
cache、persist默认都是调用persist(StorageLevel.MEMORY_ONLY)。
1、cache & persist
由于RDD本身是不存储数据的,它只是一个抽象。多个RDD之间可能存在依赖,这种现象被称为RDD的血缘关系,RDD的血缘关系在job触发的时候形成DAG。
1、如果没有将RDD进行持久化。
- 如果一个RDD同时触发2个action算子的job,
那么该RDD及其之前的父RDD都会被重复执行2次!!
- RDD计算过程中失败之后,
Spark的容错机制会从血缘关系的起点开始重新计算整个DAG!!
2、如果经过cache或者persist持久化。
- 如果一个RDD同时触发2个action算子的job,
那么只有触发的第一个job会将整个DAG执行一遍,第二个job会从cache开始计算
,这样达到了计算的重用。 - RDD计算过程中失败之后,
Spark的容错机制会从cache开始重新计算整个DAG!!
这种方式不会切断血缘关系!只会在血缘关系中添加一个cache依赖,这种方式需要通过action算子触发!!!
2 、checkpoint
与前者不同,checkpoint需要sc设置检查点目录,而且checkpoint会切断血缘关系,将RDD的最终依赖置为checkpoint,默认情况下checkpoint会在原先action提交的job的基础上再重新触发一个job,也就是2个job
,将checkpoint之前的dag重新计算一遍,存在磁盘。
- 当再checkpoint之前进行cache或者persist操作,那么checkpoint就不会启动另外的job去持久化,而是直接使用cache进行持久化,此时只有1个job
//(1) MapPartitionsRDD[1] at map at CachedDemo001.scala:16 [Memory Deserialized 1x Replicated]
//| CachedPartitions: 1; MemorySize: 24.0 B; ExternalBlockStoreSize: 0.0 B; DiskSize: 0.0 B
//| ReliableCheckpointRDD[2] at collect at CachedDemo001.scala:32 [Memory Deserialized 1x Replicated]
val rdd = ...
rdd.cache()
rdd.checkpoint()
以上是一种优化
。
这种方式会切断血缘关系,同时需要action算子进行触发,也能实现计算的重用。
3 、简单的代码
package com.shufang.cache
import com.shufang.utils.ScUtil
import org.apache.spark.SparkContext
import org.apache.spark.rdd.RDD
import org.apache.spark.storage.StorageLevel
object CachedDemo001 {
def main(args: Array[String]): Unit = {
val sc: SparkContext = ScUtil.getSc
sc.setCheckpointDir("cp")
val value: RDD[Int] = sc.makeRDD(1 to 2,1)
val rdd1: RDD[Int] = value.map {
int => {
println("@@@@")
int * 2
}
}
//查看整个依赖链路,cache before
println(rdd1.toDebugString)
//rdd1.cache()
//rdd1.persist(StorageLevel.DISK_ONLY)
rdd1.cache()
rdd1.checkpoint()
println("==================")
rdd1.collect()
rdd1.collect()
//查看整个依赖链路,cache after
println(rdd1.toDebugString)
/** 以上运行结果
* (1) MapPartitionsRDD[1] at map at CachedDemo001.scala:16 []
* | ParallelCollectionRDD[0] at makeRDD at CachedDemo001.scala:14 []
* ==================
* @@@@
* @@@@
* (1) MapPartitionsRDD[1] at map at CachedDemo001.scala:16 [Memory Deserialized 1x Replicated]
* | CachedPartitions: 1; MemorySize: 24.0 B; ExternalBlockStoreSize: 0.0 B; DiskSize: 0.0 B
* | ReliableCheckpointRDD[2] at collect at CachedDemo001.scala:32 [Memory Deserialized 1x Replicated]
*/
sc.stop()
}
}