Spark RDD 持久化

目录

 

一:应用情景

二:持久化的作用方式

三:实操

四:复习Java序列化的作用

五:类比硬盘,内存和CPU的工作关系


一:应用情景

        迭代式算法
        快速交互式应用

二:持久化的作用方式


1.再次对同一个RDD进行计算时,会复用已经持久化的RDD,不用从HDFS上重新装载数据生成

2.持久化的自动容错机制:
在持久化的RDD的任何partition丢失了,会自动的从源RDD中重新计算

3.cache()和persist()的区别在于:
cache()是persist()的一种简化方式,cache()的底层就是调用的persist()的无参版本,同时就是调用persist(MEMORY_ONLY),

4.常用策略:

MEMORY_ONLY

以非序列化的Java对象的方式持久化在JVM内存中。如果内存无法完全存储RDD所有的partition,那么那些没有持久化的partition就会在下一次需要使用它的时候,重新被计算。

MEMORY_AND_DISK

同上,但是当某些partition无法存储在内存中时,会持久化到磁盘中。下次需要使用这些partition时,需要从磁盘上读取。

MEMORY_ONLY_SER

同MEMORY_ONLY,但是会使用Java序列化方式,将Java对象序列化后进行持久化。可以减少内存开销,但是需要进行反序列化,因此会加大CPU开销。

MEMORY_AND_DSK_SER

同MEMORY_AND_DSK。但是使用序列化方式持久化Java对象。

DISK_ONLY

使用非序列化Java对象的方式持久化,完全存储到磁盘上。

MEMORY_ONLY_2

MEMORY_AND_DISK_2

等等

如果是尾部加了2的持久化级别,表示会将持久化数据复用一份,保存到其他节点,从而在数据丢失时,不需要再次计算,只需要使用备份数据即可。

5.重点:MEMORY_ONLY_SER
 对象的序列化,为什么会减少内存开销?
解:序列化后的数据会比之前小,所以存储时,会减少内存占用
1.Java 序列化:在默认情况下,Spark采用Java的ObjectOutputStream序列化一个对象。该方式适用于所有实现了java.io.Serializable的类。通过继承 java.io.Externalizable,你能进一步控制序列化的性能。Java序列化非常灵活,但是速度较慢,在某些情况下序列化的结果也比较大

2.Kryo序列化:Spark也能使用Kryo(版本2)序列化对象。Kryo不但速度极快,而且产生的结果更为紧凑(通常能提高10倍)。Kryo的缺点是不支持所有类型,为了更好的性能,你需要提前注册程序中所使用的类(class)。
 

三:实操

package cn.spark.study.core;

import org.apache.spark.SparkConf;
import org.apache.spark.api.java.JavaRDD;
import org.apache.spark.api.java.JavaSparkContext;
import org.apache.spark.storage.StorageLevel;

/**
 * 将java开发的wordcount程序部署到spark集群上运行
 * @author Administrator
 *
 */
public class Persist {
	
	public static void main(String[] args) {
		SparkConf conf = new SparkConf()
				.setAppName("Persist")
				.setMaster("local"); 
		JavaSparkContext sc = new JavaSparkContext(conf);
		
		// cache()或者persist()的使用,是有规则的
		// 必须在transformation或者textFile等创建了一个RDD之后,直接连续调用cache()或persist()才可以
		// 如果你先创建一个RDD,然后单独另起一行执行cache()或persist()方法,是没有用的
		// 而且,会报错,大量的文件会丢失
		
		JavaRDD lines = sc.textFile("E://spark//spark.txt").persist(StorageLevel.MEMORY_ONLY());
		long beginTime = System.currentTimeMillis();
		long count = lines.count();
		System.out.println(count);  
		long endTime = System.currentTimeMillis();
		System.out.println("cost " + (endTime - beginTime) + " milliseconds.");   
		
		beginTime = System.currentTimeMillis();
		count = lines.count();
		System.out.println(count);
		endTime = System.currentTimeMillis();
		System.out.println("cost "+(endTime - beginTime)+" milliseconds.");
		
		sc.close();
		
		
	}
	
}

四:复习Java序列化的作用

1.为硬盘的持久化做准备
2.跨系统的对象传输
3.减小体积,减少传输宽带

五:类比硬盘,内存和CPU的工作关系

如果说把硬盘比喻成一个大仓库,CPU比喻成加工车间,那么内存就是一个临时的小仓库。从距离上来说, 相比内存到CPU的距离和硬盘到内存的距离,内存和CPU的距离更短。
硬盘(大仓库)用来保存车间需要用的原料和最终生产出来的商品。仓库太大,取出原料和存储商品太慢,耗时间。
内存(临时小仓库):原料会先放到这里,小仓库,可以很快的找到需要的原料或商品。
CPU(车间):从内存(小仓库)里拿到原料,生产商品。中间会有半成品,半成品可以放在内存(小仓库)里。

 

你可能感兴趣的:(#,spark基础)