[笔记迁移][Spark][6]RDD持久化

1. 为什么RDD需要持久化?

RDD持久化解决的问题:
    每当Action操作执行,其之前的Transformation才会被触发,形成RDD链条。Action操作完成后,该RDD会被丢弃。当再次执行该Action操作后,又会重新读取文件填充,在大数据量的情况下,形成过程和Action操作都非常耗时,整个Spark应用性能大大降低。
    通过将RDD中的所有数据持久化到所在节点的内存中(缓存思想)以实现“一次读取,一次形成,多次复用,直接取出”。从而在很多场景下,可以大幅度提升Spark应用程序的性能。据官方文档,甚至可以提高十倍。

2. 节点如何持久化?

当RDD进行持久化操作时,每个节点都会将自己操作的RDD的partition持久化到本地内存中,并且之后在RDD的反复使用中,直接使用内存中缓存的partition。Spark自身会在Shuffle操作时进行数据的持久化,比如写入磁盘,主要是为了在节点操作失败时,避免重新计算整个过程。

3. 如何操作持久化?

只需要调用被持久化的RDD的cache()/persist()即可。在RDD第一次被计算出来时,就会直接缓存在每个节点。且Spark持久化机制自动容错,若持久化的RDD的任何partition丢失,则会自动根据来源RDD,进行Transformation重演形成该partition。
cache()与persist()的区别在于: cache()是persist()的一种简化方式,其底层调用persist(MEMORY_ONLY),将数据持久化到内存中。如果需要从内存中清楚缓存,可以使用unpersist()。

4. Demo

       public static void main(String[] args) {
            SparkConf conf = new SparkConf().setAppName("persist" ).setMaster("local");
            
            JavaSparkContext sc = new JavaSparkContext(conf );
            
            JavaRDD<String> javaRDD = sc.textFile("C:\\Users\\Z-Jay\\Desktop\\spark.txt" ).cache();
            
            
             //第一次操作 无cache 317 有cache 383
             long beginTime = System .currentTimeMillis();
            
             long count = javaRDD.count();
            
             long endTime = System .currentTimeMillis();
            
             System.out.println( "Time:"+(endTime -beginTime ));
            
            
             //第二次操作 无cache 26 有 cache 26
             beginTime = System. currentTimeMillis();
            
             count = javaRDD .count();
            
             endTime = System. currentTimeMillis();
            
             System.out.println( "Time:"+(endTime -beginTime ));
            
            
             sc.close();
      }

说明:cache()/persist()的位置规定
必须在Transformation或textFile等创建一个RDD后,直接连点调用cache()/persist()。 若先创建一个RDD,再另起一行通过引用调用cache()/persist()是没有用的。

5. 持久化策略——persist()参数StorageLevel指定

持久化级别说明
MEMORY_ONLY(默认策略)以非序列化的Java对象的方式持久化在JVM内存中。若内存无法完全存储RDD所有的partition,则当下次使用到没有被序列化的partition时重新被计算。
MEMORY_AND_DISK同MEMORY_ONLY,但当某些partition无法存储在内存中时,会持久化到磁盘中。下次需要使用这些partition时,需要从磁盘上读取。
MEMORY_ONLY_SER同MEMORY_ONLY,但使用序列化的方式持久化对象。
DISK_ONLY使用非序列化Java对象的方式持久化,完全存储到磁盘上。
MEMORY_ONLY_2,MEMORY_AND_DISK_2…如果在尾部追加持久化级别2,则将持久化数据复制一份,保存至其他节点。从而在数据丢失时,不需要再次计算,只需要使用备份数据即可。

【如何选择】
(1)若可以缓存所有数据,优先使用默认策略MEMORY_ONLY。纯内存速度最快,且没有序列化,不需要消耗CPU进行反序列化操作。
(2)若默认策略无法存储下所有数据,则使用MEMORY_ONLY_SER,将数据序列化进行存储,只是要消耗CPU进行反序列化。
(3)若需要快速的失败恢复,则选择带后缀_2的策略,进行数据备份,以便失败时,不再重新计算。
(4)DISK相关策略是下下策,有时从磁盘读取数据,还不如重新计算一次。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值