第五章_Spark核心编程_Rdd_持久化(cache&persist&checkpoint)
1.什么是Rdd持久化?
Rdd只会存储的元数据信息(切片的位置信息、Rdd的依赖关系、计算逻辑等),不会存储计算数据
Rdd可以通过Cache或者Persis或者CheckPoint方法,将前面Rdd的计算的结果缓存,默认会将数据存储到JVM的堆内存中
2.怎样将Rdd的计算结果持久化?
1.Cache 缓存 调用 persist(StorageLevel.MEMORY_ONLY) 效果: 将数据存储到JVM的堆内存中 2.Persist 缓存 调用 persist(StorageLevel.存储级别) 效果: 将数据存储到JVM的堆内存中 存储级别 级别说明 : MEMORY_ONLY : 存储到内存中(JVM的堆内存中) MEMORY_AND_DISK : 优先存储到内存,内存不足时,会溢写到磁盘 MEMORY_AND_DISK_SER : 优先存储到内存,内存不足时,会溢写到磁盘(在内存存放序列化后的数据) 3.CheckPoint sc.setCheckpointDir(path) //设置CheckPoint路径 调用 checkpoint 效果: 将数据存储到磁盘
3.什么是Rdd的 CheckPoint ?
CheckPoint 就是将Rdd的计算结果 持久化到磁盘
需要设置落盘的路径(一般是HDFS),job结束后,缓存文件不会被删除
添加 CheckPoint 的好处?
当lineage过长时,容错成本过高(任务失败后需要从头开始计算),如果再中间节点添加 CheckPoint
当任务出错后,可以从CheckPoint开始计算,减少了开销
添加 CheckPoint 的坏处?
造成重复计算,添加checkpoint后,会将checkpoint之前的计算重新再计算一遍
4.note
1.将Rdd持久化到内存中,当内存不足时,可能导致缓存失败(Rdd的缓存容错机制,缓存失败也能保证计算正确执行) 2.Rdd是按Partition缓存,各个Partiton是相对独立的,因此只需要将计算丢失的部分重新计算即可 3.Spark会自动对溢写Shuffle操作的中间数据做持久化操作(比如groupBy等) 避免Shuffle之后的计算失败后,又要重新Shuffle计算
5.cache、persist、checkpoint的区别?
* 1. cache : * 将计算结果存储到内存中 * 不涉及涉及到磁盘IO,性能较高,但是数据不安全 * 不会切断血缘关系 * 不会单独在执行一次计算任务 * * 2. persist * 将计算结果存储到内存中(指定存储级别,可临时存储到磁盘) * 涉及到磁盘IO,性能较低,但是数据安全 * 不会切断血缘关系 * 不会单独在执行一次计算任务 * job执行完毕,临时保存的数据文件就会丢失 * * 3. checkpoint * 将计算结果存储到磁盘中(通常存储在HDFS等容错、高可用的文件系统,可靠性高) * 涉及到磁盘IO,性能较低,但是数据安全 * 会切断血缘关系 * 会单独在执行一次计算任务 * job执行完毕,保存的数据文件不会丢失
6.cache、persist、checkpoint 选择原则?
* 先对Rdd 做cache操作 * 在对Rdd 做checkpoint操作 * 可以避免checkpoint的重复计算问题
7.Cache&Persist 示例
object PersistAndCache { def main(args: Array[String]): Unit = { val sparConf = new SparkConf().setMaster("local").setAppName("Persist") val sc = new SparkContext(sparConf) val rdd = sc.makeRDD(List("Hello Scala", "Hello Spark")) val flatRDD = rdd.flatMap(e => { println(s"flatMap 开始操作 ${e}") e.split(" ") } ) flatRDD.cache() val mapRDD = flatRDD.map(word => { println(s"map 开始操作 (${word},1)") (word, 1) }) mapRDD.cache() val reduceRDD: RDD[(String, Int)] = mapRDD.reduceByKey( (v1, v2) => { println(s"reduceByKey 开始操作 ${v1} + ${v2}") v1 + v2 } ) reduceRDD.collect().foreach(println) println("**************************************") val groupRDD = mapRDD.groupByKey() groupRDD.collect().foreach(println) sc.stop() } }
-- 实验组(不开启 cache) flatMap 开始操作 Hello Scala map 开始操作 (Hello,1) map 开始操作 (Scala,1) flatMap 开始操作 Hello Spark map 开始操作 (Hello,1) reduceByKey 开始操作 1 + 1 map 开始操作 (Spark,1) (Spark,1) (Hello,2) (Scala,1) ************************************** flatMap 开始操作 Hello Scala map 开始操作 (Hello,1) map 开始操作 (Scala,1) flatMap 开始操作 Hello Spark map 开始操作 (Hello,1) map 开始操作 (Spark,1) (Spark,CompactBuffer(1)) (Hello,CompactBuffer(1, 1)) (Scala,CompactBuffer(1)) --对照组(开启 cache) flatMap 开始操作 Hello Scala flatMap 开始操作 Hello Spark map 开始操作 (Hello,1) map 开始操作 (Scala,1) map 开始操作 (Hello,1) map 开始操作 (Spark,1) reduceByKey 开始操作 1 + 1 (Spark,1) (Hello,2) (Scala,1) ************************************** (Spark,CompactBuffer(1)) (Hello,CompactBuffer(1, 1)) (Scala,CompactBuffer(1))
8.checkPoint 示例
object CheckPoint { def main(args: Array[String]): Unit = { val sparConf = new SparkConf().setMaster("local").setAppName("Persist") val sc = new SparkContext(sparConf) //设置CheckPoint路径 sc.setCheckpointDir("Spark_319/src/output/checkpoint") val rdd = sc.makeRDD(List("Hello Scala", "Hello Spark")) val flatRDD = rdd.flatMap(e => { println(s"flatMap 开始操作 ${e}") e.split(" ") } ) //flatRDD.checkpoint() val mapRDD = flatRDD.map(word => { println(s"map 开始操作 (${word},1)") (word, 1) }) //mapRDD.checkpoint() val reduceRDD: RDD[(String, Int)] = mapRDD.reduceByKey( (v1, v2) => { println(s"reduceByKey 开始操作 ${v1} + ${v2}") v1 + v2 } ) reduceRDD.collect().foreach(println) println("**************************************") val groupRDD = mapRDD.groupByKey() groupRDD.collect().foreach(println) sc.stop() } }
-- 实验组(开启checkpoint)
flatMap 开始操作 Hello Scala map 开始操作 (Hello,1) map 开始操作 (Scala,1) flatMap 开始操作 Hello Spark map 开始操作 (Hello,1) reduceByKey 开始操作 1 + 1 map 开始操作 (Spark,1) flatMap 开始操作 Hello Scala map 开始操作 (Hello,1) map 开始操作 (Scala,1) flatMap 开始操作 Hello Spark(为保证数据安全,checkpoint会重新将结果计算一遍) map 开始操作 (Hello,1) map 开始操作 (Spark,1) (Spark,1) (Hello,2) (Scala,1) ************************************** (Spark,CompactBuffer(1)) (Hello,CompactBuffer(1, 1)) (Scala,CompactBuffer(1)) -- 对照组(不开启checkpoint) flatMap 开始操作 Hello Scala map 开始操作 (Hello,1) map 开始操作 (Scala,1) flatMap 开始操作 Hello Spark map 开始操作 (Hello,1) reduceByKey 开始操作 1 + 1 map 开始操作 (Spark,1) (Spark,1) (Hello,2) (Scala,1) ************************************** flatMap 开始操作 Hello Scala map 开始操作 (Hello,1) map 开始操作 (Scala,1) flatMap 开始操作 Hello Spark map 开始操作 (Hello,1) map 开始操作 (Spark,1) (Spark,CompactBuffer(1)) (Hello,CompactBuffer(1, 1)) (Scala,CompactBuffer(1))
9. Rdd Shuffle后自动缓存Rdd计算结果
object persistTest extends App { val sparkconf: SparkConf = new SparkConf().setMaster("local").setAppName("distinctTest") val sc: SparkContext = new SparkContext(sparkconf) val rdd = sc.makeRDD(List("Hello Scala", "Hello Spark")) private val rdd1: RDD[String] = rdd.flatMap( e => { println("flatMap 开始操作") e.split(" ") } ) private val rdd2: RDD[(String, Iterable[String])] = rdd1.groupBy( e => { println(s"groupBy 开始操作 ${e}") e } ) //rdd2 有shuffle操作,会自动将结果 持久化到内存 private val rdd3: RDD[(String, Int)] = rdd2.map(tp => { (tp._1, tp._2.size) }) private val rdd4: RDD[(String, String)] = rdd2.map(tp => { (tp._1, tp._2.mkString(",")) }) rdd3.collect().foreach(println(_)) println("*****开启第二个Job********************") //开启第二个job rdd4.collect().foreach(println(_)) sc.stop() }
flatMap 开始操作 groupBy 开始操作 Hello groupBy 开始操作 Scala flatMap 开始操作 groupBy 开始操作 Hello groupBy 开始操作 Spark (Spark,1) (Hello,2) (Scala,1) *****开启第二个Job******************** (Spark,Spark) (Hello,Hello,Hello) (Scala,Scala)
10. cache + checkPoint 示例
object CacheAndCheckPoint { def main(args: Array[String]): Unit = { val sparConf = new SparkConf().setMaster("local").setAppName("Persist") val sc = new SparkContext(sparConf) //设置CheckPoint路径 sc.setCheckpointDir("Spark_319/src/output/checkpoint") val rdd = sc.makeRDD(List("Hello Scala", "Hello Spark")) val flatRDD = rdd.flatMap(e => { println(s"flatMap 开始操作 ${e}") e.split(" ") } ) flatRDD.cache() flatRDD.checkpoint() val mapRDD = flatRDD.map(word => { println(s"map 开始操作 (${word},1)") (word, 1) }) mapRDD.cache() mapRDD.checkpoint() val reduceRDD: RDD[(String, Int)] = mapRDD.reduceByKey( (v1, v2) => { println(s"reduceByKey 开始操作 ${v1} + ${v2}") v1 + v2 } ) reduceRDD.collect().foreach(println) println("**************************************") val groupRDD = mapRDD.groupByKey() groupRDD.collect().foreach(println) sc.stop() } }
flatMap 开始操作 Hello Scala flatMap 开始操作 Hello Spark map 开始操作 (Hello,1) map 开始操作 (Scala,1) map 开始操作 (Hello,1) map 开始操作 (Spark,1) reduceByKey 开始操作 1 + 1 (Spark,1) (Hello,2) (Scala,1) ************************************** (Spark,CompactBuffer(1)) (Hello,CompactBuffer(1, 1)) (Scala,CompactBuffer(1))
分类:
SparkCore
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· 字符编码:从基础到乱码解决
· SpringCloud带你走进微服务的世界