RDD的Cache、Persist、Checkpoint的区别和StorageLevel存储级别划分
为了增强容错性和高可用,避免上游RDD被重复计算的大量时间开销,Spark RDD设计了包含多种存储级别的缓存和持久化机制,主要有三个概念:Cache、Persist、Checkout。
1、存储级别介绍(StorageLevel)
存储级别以一个枚举类StorageLevel定义,分为以下12种:
| 存储级别 | 使用空间 | CPU时间 | 是否在内存中 | 是否在磁盘上 | 备注 |
NONE |
否 | 否 | 否 | 否 | 不使用任何存储 |
DISK_ONLY |
低 | 高 | 否 | 是 | 只存在磁盘上 |
DISK_ONLY_2 |
低 | 高 | 否 | 是 | 数据存2份 |
MEMORY_ONLY |
高 | 低 | 是 | 否 | 只存在内存中 |
MEMORY_ONLY_2 |
高 | 低 | 是 | 否 | 数据存2份 |
MEMORY_ONLY_SER |
低 | 高 | 是 | 否 | 数据序列化存储 |
MEMORY_ONLY_SER_2 |
低 | 高 | 是 | 否 | 数据序列化后存2份 |
MEMORY_AND_DISK |
高 | 中等 | 部分 | 部分 | 若数据在内存中放不下,就溢出写到磁盘上 |
MEMORY_AND_DISK_2 |
高 | 中等 | 部分 | 部分 | 数据存2份 |
MEMORY_AND_DISK_SER |
低 | 高 | 部分 | 部分 | 数据序列化后,先存内存,内存放不下就溢写到磁盘 |
MEMORY_AND_DISK_SER_2 |
低 | 高 | 部分 | 部分 | 数据存2份 |
OFF_HEAP |
使用JVM堆外内存,利用java unsafe API实现的内存管理
|
2、Cache 和 Persist 的区别
/**
* Persist this RDD with the default storage level (`MEMORY_ONLY`).
*/
def persist(): this.type = persist(StorageLevel.MEMORY_ONLY) /**
* Persist this RDD with the default storage level (`MEMORY_ONLY`).
*/
def cache(): this.type = persist()
上面是RDD的cache和persist的源代码,可以看出,cache方法本质上调用了空参数的persist方法,而空参数的persist方法又调用了“MEMORY_ONLY”参数的persist方法,也就是说,cache是MEMORY_ONLY级别的缓存存储,是一个特殊的persist。
3、Persist
persist方法提供了丰富的存储级别,可以满足多样性的缓存需求
/**
* Mark this RDD for persisting using the specified level.
*
* @param newLevel the target storage level
* @param allowOverride whether to override any existing level with the new one
*/
private def persist(newLevel: StorageLevel, allowOverride: Boolean): this.type = {
// TODO: Handle changes of StorageLevel
if (storageLevel != StorageLevel.NONE && newLevel != storageLevel && !allowOverride) {
throw new UnsupportedOperationException(
"Cannot change storage level of an RDD after it was already assigned a level")
}
// If this is the first time this RDD is marked for persisting, register it
// with the SparkContext for cleanups and accounting. Do this only once.
if (storageLevel == StorageLevel.NONE) {
sc.cleaner.foreach(_.registerRDDForCleanup(this))
sc.persistRDD(this)
}
storageLevel = newLevel
this
} /**
* Set this RDD's storage level to persist its values across operations after the first time
* it is computed. This can only be used to assign a new storage level if the RDD does not
* have a storage level set yet. Local checkpointing is an exception.
*/
def persist(newLevel: StorageLevel): this.type = {
if (isLocallyCheckpointed) {
// This means the user previously called localCheckpoint(), which should have already
// marked this RDD for persisting. Here we should override the old storage level with
// one that is explicitly requested by the user (after adapting it to use disk).
persist(LocalRDDCheckpointData.transformStorageLevel(newLevel), allowOverride = true)
} else {
persist(newLevel, allowOverride = false)
}
} /**
* Persist this RDD with the default storage level (`MEMORY_ONLY`).
*/
def persist(): this.type = persist(StorageLevel.MEMORY_ONLY)
persist方法包含三个实现,但可以看出,空参数的persist其实调用了单参数的persist方法,单参数的persist方法又调用了双参数的persist方法,在双参数persist中排除了一种情况,之后按照最新存储级别执行存储,存储流程的细节以后再分析。
3、Checkpoint和Persist的区别
| Persist | Checkpoint | |
| 位置 | persist和cache只能保存在本地的磁盘和内存中(或者堆外内存) | 数据必须保存在HDFS分布式文件系统中 |
| 生命周期 | cache和persist的RDD会在程序结束后被清除或者可以手动调用unpersist清除 | 由于在HDFS上,程序结束结束后依然存在,不会被删除 |
| RDD血统和依赖链 |
persist和cache会保留RDD的血统和依赖关系,原因是这两种持久化方式是不可靠的。 如果出现Executor宕机等故障,那么持久化的数据就会丢失,那么修复后可以回溯血统重新计算RDD |
HDFS天然支持高可靠存储,即checkpoint的持久化就是绝对可靠的, 所以checkpoint会折断依赖链,不需要回溯 |
| 额外Job |
persist和cache有RDD血统链,不需要开启额外Job执行操作 |
checkpoint会通过sc.runJob()开启一个额外Job来执行RDD写入HDFS的操作 |
综上,可以得出,cache是一个特殊的persist,persist是保留RDD血统的不可靠持久化方式,checkpoint是安全可靠、不保留RDD血统的持久化方式; 如果不考虑OOM等异常可能性大小,且单论性能的话,Cache > Persist > Checkpoint
RDD的Cache、Persist、Checkpoint的区别和StorageLevel存储级别划分的更多相关文章
- RDD的cache 与 checkpoint 的区别
问题:cache 与 checkpoint 的区别? 关于这个问题,Tathagata Das 有一段回答: There is a significant difference between cac ...
- RDD中的cache() persist() checkpoint()
cache只有一个默认的缓存级别MEMORY_ONLY ,而persist可以根据StorageLevel设置其它的缓存级别. cache以及persist都不是action. 被重复使用的(但是)不 ...
- Spark cache、checkpoint机制笔记
Spark学习笔记总结 03. Spark cache和checkpoint机制 1. RDD cache缓存 当持久化某个RDD后,每一个节点都将把计算的分片结果保存在内存中,并在对此RDD或衍生出 ...
- RDD中cache和persist的区别
通过观察RDD.scala源代码即可知道cache和persist的区别: def persist(newLevel: StorageLevel): this.type = { if (storage ...
- Checkpoint & cache & persist
checkpoint checkpoint(检查点)是Spark为了避免长链路,大计算量的Rdd不可用时,需要长时间恢复而引入的.主要就是将通过大量计算而获得的这类Rdd的数据直接持久化到外部可靠的存 ...
- Spark(七)【RDD的持久化Cache和CheckPoint】
RDD的持久化 1. RDD Cache缓存 RDD通过Cache或者Persist方法将前面的计算结果缓存,默认情况下会把数据以缓存在JVM的堆内存中.但是并不是这两个方法被调用时立即缓存,而是 ...
- HttpContext.Cache和Application的区别
原文:HttpContext.Cache和Application的区别 (转载) 应用程序级的Cache和Application用户会话级的Session application的缺点是在读取时最 ...
- cache 和 buffer的区别
cache 和 buffer的区别: Cache:高速缓存,是位于CPU与主内存间的一种容量较小但速度很高的存储器.由于CPU的速度远高于主内存, CPU直接从内存中存取数据要等待一定时间周期,Cac ...
- Linux Free命令每个数字的含义 和 cache 、buffer的区别
Linux Free命令每个数字的含义 和 cache .buffer的区别 我们按照图中来一细细研读(数字编号和图对应)1,total:物理内存实际总量2,used:这块千万注意,这里可不是实际已经 ...
随机推荐
- POI之下载模板(或各种文件)
该例基于Nutz框架 前台代码: <a href="" id="errordownload" onclick="downloadErrorLog ...
- Vue数据绑定(一)
Contents Vue作为当下炙手可热的前端三大框架之一,一直都想深入研究一下其内部的实现原理,去学习MVVM模式的精髓.如果说MVVM是当下最流行的图形用户界面开发模式,那么数据绑定则是这一模式的 ...
- BEM命名及其在sass中的实践
Why use it 近几年web应用的发展可以用疯狂来形容,依靠浏览器的支持以及前端技术和框架的发展,很多应用已经把大量的逻辑从服务器端迁移到了浏览器端,使用前后端分离技术,浏览器端与用户进行交互来 ...
- Java基础--Arrays类
Arrays工具类:用来操作数组(比如排序和搜索)的各种方法 常用方法: 使用二分法查找 Arrays.binarySearch(int[]array,int value); 数组内容转换成字符串的形 ...
- Yuchuan_Linux_C 编程之十 进程及进程控制
一.整体大纲 二.基础知识 1. 进程相关概念 1)程序和进程 程序,是指编译好的二进制文件,在磁盘上,不占用系统资源(cpu.内存.打开的文件.设备.锁....) 进程,是一个抽象的概念,与 ...
- 2020 新个税算的头疼?会 python,这都不是事儿...
背景 今年疫情复工后,财务小姐姐给我们普及了2020年新个税的算法.. 听完之后的感觉就是:恩,原来是这么回事! 虽然是个小工薪阶级,但是对于扣多少税还是很关心的.于是拿起笔算了算2月份的个税,产生了 ...
- javax.email 发送邮件 javaEmail ,java 邮件
首先导入mail的jar包 然后代码如下 package aaa; import java.util.Date;import java.util.Properties; import javax.ma ...
- 基于 HTML + WebGL 结合 23D 的疫情地图实时大屏 PC 版
前言 2019年12月以来,湖北省武汉市陆续发现了多例肺炎病例,现已证实为一种新型冠状病毒感染引起的急性呼吸道传染病并蔓延全国,肺炎疫情牵动人心,人们每天起来第一件事变成了关注疫情进展,期望这场天灾早 ...
- GitHub 热点速览 Vol.11:回暖的 GitHub 迎来上千星的图片流项目
作者:HelloGitHub-小鱼干 摘要:连着两周成绩平平的 GitHub Trending 榜,终于和三月的天气一样进入全面变暖的模式,无论是本周刚开源搭乘 ocr 热点并获得 1,500+ st ...
- C++ 小练习,一个整型数字的处理
#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> //输入一个任意位数的int整数,并判断该整数的位数,并输出每一位数(每个数字中间用空 ...