Spark中的RDD缓存----cache
目录
- Spark中的RDD缓存----cache
- RDD缓存代码示例
- RDD的缓存级别
前面说到,spark中的RDD是没有数据的,因为数据流过而不留下,
有时候对同一个RDD我们需要使用多次,每次使用该RDD,数据都要重新调用,非常麻烦;
这时候我们可以通过对RDD进行缓存,将RDD缓存在内存或者磁盘里面,
这样就使RDD中含有数据了。
RDD缓存代码示例
package com.shujia.spark
import org.apache.spark.rdd.RDD
import org.apache.spark.{SparkConf, SparkContext}
object Demo23Cache {
def main(args: Array[String]): Unit = {
val conf: SparkConf = new SparkConf()
.setAppName("Demo23Cache")
.setMaster("local")
val sc = new SparkContext(conf)
//读取文件创建RDD
val studentsRDD: RDD[String] = sc.textFile("data/students.txt")
//拆分数据
val studentsTupleRDD: RDD[(String, String, Int, String, String)] = studentsRDD.map(stu => {
val split: Array[String] = stu.split(",")
(split(0), split(1), split(2).toInt, split(3), split(4)) //整理成元组的形式输出
})
/**
* 当同一个RDD多次使用的时候,可以将这个RDD缓存---cache
*/
studentsTupleRDD.cache()
/**
* 统计班级人数
*/
//取出班级
val clazzRDD: RDD[(String, Int)] = studentsTupleRDD.map{
case (id:String, name:String, age:Int, gender:String, clazz:String)=>
(clazz,1)
}
/*
在case匹配的时候,只用到了一个列,其他的没用上,那么其他的列可以用下划线代替
case (_:String, _:String, _:Int, _:String, _:String)=>
*/
//按照key聚合value
val clazzNumRDD: RDD[(String, Int)] = clazzRDD.reduceByKey((x, y) => x + y)
clazzNumRDD.foreach(println)
//(理科二班,79)
//(文科三班,94)
/**
* 统计性别人数
*/
val genderRDD: RDD[(String, Int)] = studentsTupleRDD.map{
case (_:String, _:String, _:Int, gender:String, _:String) =>
(gender,1)
}
val genderNumRDD: RDD[(String, Int)] = genderRDD.reduceByKey((x, y) => x + y)
genderNumRDD.foreach(println)
}
}
第一个action算子,就触发了一次任务,程序开始从头到尾执行一遍--->统计了班级人数;
第二个action算子,也触发了一次任务,程序也开始从头到尾执行一遍-->统计了性别人数;
studentsTupeRDD之前的包括自身都被执行了两遍
添加RDD缓存
cache的流程:
当第一个Job在执行的时候发现RDD执行cache,会将RDD的数据缓存起来;
下一个Job如果再使用这个RDD,可以直接从缓存中读取数据,不需要重新计算这个RDD;
缓存的数据在Executor中,
默认缓存的级别MEMORY_ONLY,只存内存
默认值 --executor-memory 512m--num-executor 2
总的内存是512*2=1G,缓存可以使用0.6(600M),
如果RDD的数据超过了600M,会出现内存溢出
RDD的缓存级别