持久化的作用,供RDD的重复使用,针对计算耗时比较长,可以提高计算的效率,针对数据比较重要的数据保存到持久化中,数据的安全性也可以得到保障。
以WordCount为例
在map操作后可以使用reduceByKey也可以使用groupByKey
但是无论是用哪种方法,都必须从数据源从头开始
持久化操作后,针对数据比较重要的数据保存到持久化中
def main(args: Array[String]): Unit = {
val sparkConf: SparkConf = new SparkConf().setMaster("local").setAppName("wordcount")
val sc = new SparkContext(sparkConf)
println("===========reduceByKey操作=============")
val list = List("Hello Scala", "Hello Spark")
val rdd: RDD[String] = sc.makeRDD(list)
val flatRDD: RDD[String] = rdd.flatMap(_.split(" "))
val mapRDD: RDD[(String, Int)] = flatRDD.map(word =>{
//这里map操作设置了打印操作,来方便区别
println("@@@@@@@@@@")
(word,1)
})
val reduceRDD: RDD[(String, Int)] = mapRDD.reduceByKey(_ + _)
reduceRDD.collect().foreach(println)
println("===========groupByKey操作=============")
val groupRDD= mapRDD.groupByKey()
groupRDD.collect().foreach(println)
sc.stop()
}
cache 操作会增加血缘关系,不改变原有的血缘关系
RDD 通过 Cache 或者 Persist 方法将前面的计算结果缓存,默认情况下会把数据以缓存在 JVM 的堆内存中。但是并不是这两个方法被调用时立即缓存,而是触发后面的 action 算子时,该 RDD 将会被缓存在计算节点的内存中,并供后面重用。
def main(args: Array[String]): Unit = {
val sparkConf: SparkConf = new SparkConf().setMaster("local").setAppName("wordcount")
val sc = new SparkContext(sparkConf)
println("===========reduceByKey操作=============")
val list = List("Hello Scala", "Hello Spark")
val rdd: RDD[String] = sc.makeRDD(list)
val flatRDD: RDD[String] = rdd.flatMap(_.split(" "))
val mapRDD: RDD[(String, Int)] = flatRDD.map(word =>{
//这里map操作设置了打印操作,来方便区别
println("@@@@@@@@@@")
(word,1)
})
/**
* cache默认持久化操作,只能将数据保存到内存中,
* 如果想要保存到磁盘当中
* 需要更改存储级别
*/
mapRDD.cache()//放入内存当中
val reduceRDD: RDD[(String, Int)] = mapRDD.reduceByKey(_ + _)
reduceRDD.collect().foreach(println)
println("===========groupByKey操作=============")
val groupRDD= mapRDD.groupByKey()
groupRDD.collect().foreach(println)
sc.stop()
}
不改变原有的血缘关系
保存成临时文件,作业结束后,文件会消失
可以更改存储级别
mapRdd.persist(StorageLevel.MEMORY_AND_DISK_2)
存储级别
object 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 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)
def main(args: Array[String]): Unit = {
val sparkConf: SparkConf = new SparkConf().setMaster("local").setAppName("wordcount")
val sc = new SparkContext(sparkConf)
println("===========reduceByKey操作=============")
val list = List("Hello Scala", "Hello Spark")
val rdd: RDD[String] = sc.makeRDD(list)
val flatRDD: RDD[String] = rdd.flatMap(_.split(" "))
val mapRDD: RDD[(String, Int)] = flatRDD.map(word =>{
//这里map操作设置了打印操作,来方便区别
println("@@@@@@@@@@")
(word,1)
})
/**
* 如果想要保存到磁盘当中
* 需要更改存储级别
* 持久化操作必须在行动算子执行时完成的
*/
mapRDD.persist(StorageLevel.DISK_ONLY)
val reduceRDD: RDD[(String, Int)] = mapRDD.reduceByKey(_ + _)
reduceRDD.collect().foreach(println)
println("===========groupByKey操作=============")
val groupRDD= mapRDD.groupByKey()
groupRDD.collect().foreach(println)
sc.stop()
}
检查点路径保存的文件,当作业执行完毕后,不会被删除
以WordCount为例,这里检查点路径设置保存在本地
def main(args: Array[String]): Unit = {
val sparkConf: SparkConf = new SparkConf().setMaster("local").setAppName("wordcount")
val sc = new SparkContext(sparkConf)
// 设置检查点路径
sc.setCheckpointDir("cp")
val list = List("Hello Scala", "Hello Spark")
val rdd: RDD[String] = sc.makeRDD(list)
val flatRDD: RDD[String] = rdd.flatMap(_.split(" "))
val mapRDD: RDD[(String, Int)] = flatRDD.map(word =>{
println("@@@@@@@@@@@@")
(word,1)
})
/**
* 检查点
* checkpoint
* 需要落盘,需要指定检查点保存路径
* 可以重复使用
* 检查点路径保存的文件,当作业执行完毕后,不会被删除
* 一般保存路径都是在分布式储存系统:HDFS
*/
mapRDD.checkpoint()
val reduceRDD: RDD[(String, Int)] = mapRDD.reduceByKey(_ + _)
reduceRDD.collect().foreach(println)
println("==============================")
val groupRDD= mapRDD.groupByKey()
groupRDD.collect().foreach(println)
sc.stop()
}
执行过程中,会切断血缘关系。重新建立新的血缘关系。因为读取数据的数据源发生了改变
可以配合cache使用,这样checkpoint的job只需从Cache缓存中读取数据即可
// 增加缓存,避免再重新跑一个 job 做 checkpoint
mapRDD.cache()
// 数据检查点:针对 wordToOneRdd 做检查点计算
mapRDD.checkpoint()
总结