Spark RDD持久化机制

news/2024/11/8 3:42:20/

文章目录

  • 一、RDD持久化
    • (一)引入持久化的必要性
    • (二)案例演示持久化操作
      • 1、RDD的依赖关系图
      • 2、不采用持久化操作
      • 3、采用持久化操作
  • 二、存储级别
    • (一)持久化方法的参数
    • (二)Spark RDD存储级别表
    • (三)如何选择存储级别
    • (四)persist()与cache()的关系
    • (五)案例演示设置存储级别
  • 三、利用Spark WebUI查看缓存
    • (一)创建RDD并标记为持久化
    • (二)Spark WebUI查看RDD存储信息
    • (三)将RDD从缓存中删除


一、RDD持久化

在这里插入图片描述

(一)引入持久化的必要性

Spark中的RDD是懒加载的,只有当遇到行动算子时才会从头计算所有RDD,而且当同一个RDD被多次使用时,每次都需要重新计算一遍,这样会严重增加消耗。为了避免重复计算同一个RDD,可以将RDD进行持久化。

Spark中重要的功能之一是可以将某个RDD中的数据保存到内存或者磁盘中,每次需要对这个RDD进行算子操作时,可以直接从内存或磁盘中取出该RDD的持久化数据,而不需要从头计算才能得到这个RDD。

(二)案例演示持久化操作

1、RDD的依赖关系图

读取文件,进行一系列操作,有多个RDD,如下图所示。
在这里插入图片描述

2、不采用持久化操作

在上图中,对RDD3进行了两次算子操作,分别生成了RDD4和RDD5。若RDD3没有持久化保存,则每次对RDD3进行操作时都需要从textFile()开始计算,将文件数据转化为RDD1,再转化为RDD2,最终才得到RDD3。

查看要操作的HDFS文件
在这里插入图片描述
以集群模式启动Spark Shell
在这里插入图片描述
按照图示进行操作,得RDD4和RDD5
在这里插入图片描述
查看RDD4内容,会从RDD1到RDD2到RDD3到RDD4跑一趟
在这里插入图片描述
显示RDD5内容,也会从RDD1到RDD2到RDD3到RDD5跑一趟
在这里插入图片描述

3、采用持久化操作

可以在RDD上使用persist()或cache()方法来标记要持久化的RDD(cache()方法实际上底层调用的是persist()方法)。在第一次行动操作时将对数据进行计算,并缓存在节点的内存中。Spark的缓存是容错的:如果缓存的RDD的任何分区丢失,Spark就会按照该RDD原来的转换过程自动重新计算并缓存。

计算到RDD3时,标记持久化
在这里插入图片描述
计算RDD4,就是基于RDD3缓存的数据开始计算,不用从头到尾跑一趟
在这里插入图片描述
计算RDD5,就是基于RDD3缓存的数据开始计算,不用从头到尾跑一趟
在这里插入图片描述

二、存储级别

(一)持久化方法的参数

利用RDD的persist()方法实现持久化,向persist()方法中传入一个StorageLevel对象指定存储级别。每个持久化的RDD都可以使用不同的存储级别存储,默认的存储级别是StorageLevel.MEMORY_ONLY。

(二)Spark RDD存储级别表

Spark RDD有七种存储级别

存储级别说明
MEMORY_ONLY将RDD存储为JVM中的反序列化Java对象。如果内存不够,部分分区就不会被缓存,并且在每次需要这些分区的时候都会被动态地重新计算。此为默认级别。
MEMORY_AND_DISK将RDD存储为JVM中的反序列化Java对象。如果内存不够,就将未缓存的分区存储在磁盘上,并在需要这些分区时从磁盘读取。
MEMORY_ONLY_SER将RDD存储为序列化的Java对象(每个分区一个字节数组)。这通常比反序列化对象更节省空间,特别是在使用快速序列化时,但读取时会增加 CPU负担。
MEMORY_AND_DISK_SER类似于MEMORY_ONLY_SER,但是溢出的分区将写到磁盘,而不是每次需要对其动态地重新计算。
DISK_ONLY只在磁盘上存储RDD分区。
MEMORY_ONLY_2与MEMORY_ONLY 相同,只是每个持久化的分区都会复制一份副本,存储在其他节点上。这种机制主要用于容错,一旦持久化数据丢失,可以使用副本数据,而不需要重新计算。
MEMORY_AND_DISK_2与MEMORY_AND_DISK相同,只是每个持久化的分区都会复制一份副本,存储在其他节点上。这种机制主要用于容错,一旦持久化数据丢失,可以使用副本数据,而不需要重新计算。

在Spark的Shuffle操作(例如reduceByKey()中,即使用户没有使用persist()方法,也会自动保存一些中间数据。这样做是为了避免在节点洗牌的过程中失败时重新计算整个输入。如果想多次使用某个RDD,那么强烈建议在该RDD上调用persist()方法。

(三)如何选择存储级别

选择原则:权衡内存使用率和CPU效率

如果RDD存储在内存中不会发生溢出,那么优先使用默认存储级别(MEMORY_ONLY),该级别会最大程度发挥CPU的性能,使在RDD上的操作以最快的速度运行。

如果RDD存储在内存中会发生溢出,那么使用MEMORY_ONLY_SER并选择一个快速序列化库将对象序列化,以节省空间,访问速度仍然相当快。

除非计算RDD的代价非常大,或者该RDD过滤了大量数据,否则不要将溢出的数据写入磁盘,因为重新计算分区的速度可能与从磁盘读取分区一样快。

如果希望在服务器出故障时能够快速恢复,那么可以使用多副本存储级别MEMORY_ONLY_2或MEMORY_AND_DISK_2。该存储级别在数据丢失后允许在RDD上继续运行任务,而不必等待重新计算丢失的分区。其他存储级别在发生数据丢失后,需要重新计算丢失的分区。

(四)persist()与cache()的关系

查看两个方法的源码

/**                                                                                           * 在第一次行动操作时持久化RDD,并设置存储级别,当RDD从来没有设置过存储级别时才能使用该方法                                           */                                                                                          
def persist(newLevel: StorageLevel): this.type = {                                            if (isLocallyCheckpointed) {                                                                // 如果之前已将该RDD设置为localCheckpoint,就覆盖之前的存储级别                                                persist(LocalRDDCheckpointData.transformStorageLevel(newLevel), allowOverride = true)     } else {                                                                                    persist(newLevel, allowOverride = false)                                                  }                                                                                           
}                                                                                             
/**                                                                                           * 持久化RDD,使用默认存储级别(MEMORY_ONLY)                                                              */                                                                                          
def persist(): this.type = persist(StorageLevel.MEMORY_ONLY)                                  /**                                                                                           * 持久化RDD,使用默认存储级别(MEMORY_ONLY)                                                              */                                                                                          
def cache(): this.type = persist()                                                            

从上述代码可以看出,cache()方法调用了无参的persist()方法,两者的默认存储级别都为MEMORY_ONLY,但cache()方法不可更改存储级别,而persist()方法可以通过参数自定义存储级别。

(五)案例演示设置存储级别

在net.army.rdd根包里创建day05子包,然后在子包里创建SetStorageLevel对象
在这里插入图片描述
运行程序,查看结果
在这里插入图片描述

三、利用Spark WebUI查看缓存

使用集群方式重启Spark Shell
在这里插入图片描述

(一)创建RDD并标记为持久化

执行命令:val rdd = sc.parallelize(List(56, 67, 32, 89, 90, 66, 100))
在这里插入图片描述

(二)Spark WebUI查看RDD存储信息

浏览器中访问Spark Shell的WebUI http://master:4040/storage/ 查看RDD存储信息,可以看到存储信息为空
在这里插入图片描述
执行命令:rdd.collect,收集RDD数据
在这里插入图片描述
刷新WebUI,发现出现了一个ParallelCollectionRDD的存储信息,该RDD的存储级别为MEMORY,持久化的分区为8,完全存储于内存中。
在这里插入图片描述
单击ParallelCollectionRDD超链接,可以查看该RDD的详细存储信息
在这里插入图片描述

上述操作说明,调用RDD的persist()方法只是将该RDD标记为持久化,当执行行动操作时才会对标记为持久化的RDD进行持久化操作。

执行以下命令,创建rdd2,并将rdd2持久化到磁盘
在这里插入图片描述
刷新WebUI,发现多了一个MapPartitionsRDD的存储信息,该RDD的存储级别为DISK,持久化的分区为8,完全存储于磁盘中。
在这里插入图片描述

(三)将RDD从缓存中删除

Spark会自动监视每个节点上的缓存使用情况,并以最近最少使用的方式从缓存中删除旧的分区数据。如果希望手动删除RDD,而不是等待该RDD被Spark自动从缓存中删除,那么可以使用RDD的unpersist()方法。

执行命令:rdd.unpersist(),将rdd(ParallelCollectionRDD)从缓存中删除
在这里插入图片描述

刷新WebUI,发现只剩下了MapPartitionsRDD,ParallelCollectionRDD已被移除。
在这里插入图片描述


http://www.ppmy.cn/news/240528.html

相关文章

智能监控和汽车领域中的网络边缘嵌入式视觉最佳选择——低功耗ECP5 FPGA LFE5U-25F-8BG256I 莱迪思深力科

莱迪思深力科LFE5U-25F-8BG256I,属于ECP5系列。它拥有24,300个LUT(Look-Up Table),可编程逻辑块,是一款高性能的可编程逻辑器件,具有高性能、灵活性和可编程性的FPGA芯片,适用于多个领域的高性能…

什么是Linux shell—一个简单的案例

一句话概括:简单来说脚本就是将需要执行的命令保存到文本中,按照顺序执行(由上往下执行),shell脚本:shell脚本就是一些命令的集合。 一、创建第一个Shell脚本:输出helloworld 1.脚本格式 脚本…

windows物理机如何迁移到VMware集群里简单教程

前言 快速将本地和远程物理机转换为虚拟机,而无需停机。同时转换可实现大规模虚拟化实施。提供对源物理机。 VMware和Microsoft 虚拟机格式以及某些第三方磁盘映像格式的广泛支持。 它可以自动从物理机(运行Windows和Linux)和从其他虚拟机格…

Excel VBA代码密码破解

1.查看VBA代码,有密码 2.破解密码: 2.1:修改文件名后缀,修改为压缩包格式 2.2:打开压缩包文件,找到文件:vbaProject.bin 2.3:把这个文件从压缩包中拖出来 2.4:打开.bi…

《C++高级编程》读书笔记(一:C++和标准库速成)

1、参考引用 C高级编程(第4版,C17标准)马克葛瑞格尔 2、建议先看《21天学通C》 这本书入门,笔记链接如下 21天学通C读书笔记(文章链接汇总) 1. C 基础知识 1.1 小程序 “hello world” // helloworld.cpp…

氮氧发动机设备 手动馅饼机 自动式鞋底切割机 高清碎纸机 1200毫米混合式3D打印机 椰子半自动剥壳机…设计

发动机活塞内燃机车头自动布胶带机自动上盖上料机无人机发动机发动机352柴油机车发动机手动折弯机偏心压机发动机306蜂蜜萃取机电动机车回转式辊道输送机600x600 3D打印机铰接式带式输送机3000运输机水冷工作站计算机松包机阀ID测试机器无人机气动发动机发动机 (附动…

AMD黑苹果遇到的问题-机械键盘输入异常

闲来无事搞了个黑苹果,体验效果很好,但是遇到了一些问题,来分享下。 使用usb的机械键盘输入异常,比如打字的时候会有一两个按键反应特别慢。 -解决:在网上找到自己机械键盘开启全键无冲突的快捷键,开启这个…

非苹果专用键盘对应ctrl修改

非苹果键盘:不想改: winc ---对应 ---ctrlc 修改:系统偏好设置--键盘--修饰键--Command 和Contrl 换一下位置[每次换键盘都得设置] Mac内置键盘control、option、command快捷键, 当接入Win键位键盘时,win对应command…