spark从入门到放弃六: RDD 持久化原理

122 篇文章 15 订阅

文章地址:http://www.haha174.top/article/details/252484
spark 中一个非常重要的功能特性就是可以将RDD 持久化到内存中。当对RDD进行持久化操作时,每个节点都会将自己操作的RDD的partition持久化到内存中,并且之后对该RDD的反复使用直接使用内存缓存的partion.这样的话针对一个RDD反复执行多个操作的场景就只要对RDD计算一次即可。后面直接使用该RDD,而不是需要反复多次计算该RDD。
巧妙的使用RDD的持久化甚至在某些场景下。可以将spark应用程序的性能提升10倍。对于迭代式算法和快速交互式应用来说RDD持久话是非常重要的。
要持久化一个RDD。只要调用其cache()方法或者persist方法即可。在该RDD第一次被计算出来时,就会直接缓存在每一个节点。而且spark持久化机制还是自动容错的。如果持久化的RDD的任何partion丢失了,那么soark会自动通过其源RDD使用transformation 操作重新计算该partion。
那么cache方法和persist方法有什么区别呢区别在于 cache 是 persist 方法的一种简化方式。cache()的底层就是调用persist的无参版本。同时调用persist(MEMORY_ONLY),将数据持久化到内存中。如果需要从内存中清除缓存那么可以使用unpersist()方法。
spark自己也会在shuffle 操作时,进行数据持久化。比如写入磁盘,主要是为了在节点失败时,避免需要重新计算整个过程。

假设我们不使用RDD持久话会出现什么呢
这里写图片描述
由图可知 假设我们需要做两次count 但是没有做持久化的话 需要从hdfs 读取两次如果数据量比较大的话会非常影响性能。
持久化如下:
这里写图片描述

cache 和persisit 使用 如下
下面给出java 示例:

public class Persist {
    static SparkConf conf=new SparkConf().setMaster("local").setAppName("persist");
   static  JavaSparkContext sc=new JavaSparkContext(conf);
    public static void main(String[] args){

       // noCache();
        cache();

    }
    public static void noCache(){

        JavaRDD<String> list=sc.textFile("C:\\Users\\haha174\\Desktop\\data\\test\\hive-site.xml");
        long beginTime=System.currentTimeMillis();
        long count=list.count();
        System.out.println("无持久化第一次"+(System.currentTimeMillis()-beginTime));


        beginTime=System.currentTimeMillis();
        count=list.count();
        System.out.println("无持久化第二次"+(System.currentTimeMillis()-beginTime));
    }
    public static void cache(){

        JavaRDD<String> list=sc.textFile("C:\\Users\\haha174\\Desktop\\data\\test\\hive-site.xml").cache();
        long beginTime=System.currentTimeMillis();
        long count=list.count();
        System.out.println("持久化第一次"+(System.currentTimeMillis()-beginTime));


        beginTime=System.currentTimeMillis();
        count=list.count();
        System.out.println("持久化第二次"+(System.currentTimeMillis()-beginTime));
    }
}

RDD的持久化是可以手动选择不同的持久化策略的。比如可以将RDD持久化到内存中,持久化到磁盘上,使用序列化的方式持久化,多持久化的数据进行多路复用。只要在调用persist()时传入对应的StorageLevel即可。

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

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

MEMORY_ONLY_SER

同MEMORY_ONLY 但是会使用java序列化方式。将java 对象序列化后进行持久化可以减少内存开销。但是需要进行反序列化会增大cpu 开销

欢迎关注,更多惊喜等着你

这里写图片描述

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值