Spark控制算子
1. 控制算子分类
Spark中控制算子也是懒执行的,需要Action算子触发才能执行,主要是为了对数据进行缓存。
cache(),persist(),checkpoint()算子
其中【cache () = persist()=persist(StorageLevel.Memory_Only)】
以上算子都可以将RDD持久化,持久化的最小单位是partition。
SparkConf conf = new SparkConf();
conf.setMaster("local").setAppName("CacheTest");
JavaSparkContext jsc = new JavaSparkContext(conf);
JavaRDD<String> lines = jsc.textFile("./NASA_access_log_Aug95");
lines = lines.cache();
long startTime = System.currentTimeMillis();
long count = lines.count();//count是action算子,到这里才能触发cache执行,所以这一次count加载是从磁盘读数据,然后拉回到driver端。
long endTime = System.currentTimeMillis();
System.out.println("共"+count+ "条数据,"+"初始化时间+cache时间+计算时间="+
(endTime-startTime));
long countStartTime = System.currentTimeMillis();
long countrResult = lines.count();//这一次是从内存种中读数据
long countEndTime = System.currentTimeMillis();
System.out.println("共"+countrResult+ "条数据,"+"计算时间="+ (countEndTime-
countStartTime));
jsc.stop();
2. persist持久化级别
如下:
1、MEMORY_AND_DISK 意思是先往内存中放数据,内存不够再放磁盘
2、最常用的是MEMORY_ONLY和MEMORY_AND_DISK。”_2”表示有副本数。
3、选择的原则是:首先考虑内存,然后考虑序列化之后再放入内存,最后考虑内存加磁盘。
4、尽量避免使用“_2”和DISK_ONLY级别。
5、deserialized是不序列化的意思。
3.注意事项
1、cache和persist都是懒执行,必须有一个action类算子触发执行。
2、cache和persist算子的返回值可以赋值给一个变量,在其他job中直接使用这个变量就是使用持久化的数据了。持久化的单位是partition。
3、cache和persist算子后不能立即紧跟action算子。如下:
错误做法:
rdd.cache().count();
因为rdd.cache()返回的不是持久化的RDD,而是一个数值了
正确做法:
JavaRDD<String> lines = jsc.textFile("./NASA_access_log_Aug95");
lines = lines.cache();
long count = lines.count();
4.Checkpoint(对Lineage非常长时使用)
1、Checkpoint概念和特征:
1>.不仅可以将数据持久化到磁盘,还可以切断RDD之间的依赖关系,checkpoint也是懒执行。
2>.Checkpoint不仅存储结果,还会存储逻辑,还可以存储元数据。
3>.Persisit切断不了RDD的依赖关系。
2、优化checekpoint
1>.因为最后是要触发当前application的action算子,所以在触发之前加一层cache操作,一样会往前执行cache操作,实现对数据的cache ,所以考虑将cache优化到checkpoi的优化流程里。
2>.对RDD执行checkpoint之前,最好对这个RDD先执行cache,这样新启动的job(回溯完成之后重新开的job)只需要将内存中的数据(cache缓存好的checkpoint那个点的数据)拷贝到HDFS上就可以。
3>.省去了重新计算这一步,不需要重头开始来走到checkpoint这个点了。
3、Checkpoint算子的执行流程?
Checkpoint:设置检查点(懒执行),可以将RDD的数据持久化到HDFS上,以切断RDD的依赖关系。
执行流程:
1>.在我们RDD的job执行完成后,他会从finalRDD(最后一个RDD)从后往前回溯。
2>.回溯的时候发现某一个RDD设置了检查点,他会对这个RDD做一个标记。
3>.全部回溯完成后,他会重新启动一个(checkpointRDD)job,来重新计算这个RDD的值,同时将这个RDD的值写入到HDFS上。
优化:谁要设置检查点,最好在设置之前进行cache一把放入内存
这个RDD的依赖关系会被切断,统一改为checkpointRDD。
注意事项:如果在一个RDD的job里面会有多个RDD设置了检查点,那么在RDD的job执行完成后,只需要启动一个checkpoint job就可以了。job寻找持久化的数据的顺序是:cache/persist-->checkpoint-->再基于他的父RDD重新计算。
文章仅作个人学习,部分摘自他处,内容不断更新