spark中的cache和persist的区别
在使用中一直知其然不知其所以然的地使用RDD.cache(),系统的学习之后发现还有一个与cache功能类似看起来冗余的persist
点进去一探究竟之后发现cache()是persist()的特例,persist可以指定一个StorageLevel。StorageLevel的列表可以在StorageLevel 伴生单例对象中找到:
cache的源码:
/** Persist this RDD with the default storage level (`MEMORY_ONLY`). */
def cache(): this.type = persist()
persist的源码:
/** Persist this RDD with the default storage level (`MEMORY_ONLY`). */
def persist(): this.type = persist(StorageLevel.MEMORY_ONLY)
区别就是cache默认是在内存中存储的,而persist可以设置存储的级别:
| 持久化级别 | 含义解释 |
|---|---|
| MEMORY_ONLY | 使用未序列化的Java对象格式,将数据保存在内存中。如果内存不够存放所有的数据,则数据可能就不会进行持久化。那么下次对这个RDD执行算子 操作时,那些没有被持久化的数据,需要从源头处重新计算一遍。这是默认的持久化策略,使用cache()方法时,实际就是使用的这种持久化策略。 |
| MEMORY_AND_DISK | 使用未序列化的Java对象格式,优先尝试将数据保存在内存中。如果内存不够存放所有的数据,会将数据写入磁盘文件中,下次对这个RDD执行算子时,持久化在磁盘文件中的数据会被读取出来使用。 |
| MEMORY_ONLY_SER | 基本含义同MEMORY_ONLY。唯一的区别是,会将RDD中的数据进行序列化,RDD的每个partition会被序列化成一个字节数组。这种方式更加节省内存,从而可以避免持久化的数据占用过多内存导致频繁GC。 |
| MEMORY_AND_DISK_SER | 基本含义同MEMORY_AND_DISK。唯一的区别是,会将RDD中的数据进行序列化,RDD的每个partition会被序列化成一个字节数组。这种方式更加节省内存,从而可以避免持久化的数据占用过多内存导致频繁GC。 |
| DISK_ONLY | 使用未序列化的Java对象格式,将数据全部写入磁盘文件中。 |
| MEMORY_ONLY_2, MEMORY_AND_DISK_2, 等等. | 对于上述任意一种持久化策略,如果加上后缀_2,代表的是将每个持久化的数据,都复制一份副本,并将副本保存到其他节点上。这种基于副本的持久化 机制主要用于进行容错。假如某个节点挂掉,节点的内存或磁盘中的持久化数据丢失了,那么后续对RDD计算时还可以使用该数据在其他节点上的副本。如果没有 副本的话,就只能将这些数据从源头处重新计算一遍了。 |
如何选择一种最合适的持久化策略
- 默认情况下,性能最高的当然是MEMORY_ONLY,但前提是你的内存必须足够足够大,可以绰绰有余地存放下整个RDD的所有数据。因为 不进行序列化与反序列化操作,就避免了这部分的性能开销;对这个RDD的后续算子操作,都是基于纯内存中的数据的操作,不需要从磁盘文件中读取数据,性能 也很高;而且不需要复制一份数据副本,并远程传送到其他节点上。但是这里必须要注意的是,在实际的生产环境中,恐怕能够直接用这种策略的场景还是有限的, 如果RDD中数据比较多时(比如几十亿),直接用这种持久化级别,会导致JVM的OOM内存溢出异常。
- 如果使用MEMORY_ONLY级别时发生了内存溢出,那么建议尝试使用MEMORY_ONLY_SER级别。该级别会将RDD数据序列化 后再保存在内存中,此时每个partition仅仅是一个字节数组而已,大大减少了对象数量,并降低了内存占用。这种级别比MEMORY_ONLY多出来 的性能开销,主要就是序列化与反序列化的开销。但是后续算子可以基于纯内存进行操作,因此性能总体还是比较高的。此外,可能发生的问题同上,如果RDD中 的数据量过多的话,还是可能会导致OOM内存溢出的异常。
- 如果纯内存的级别都无法使用,那么建议使用MEMORY_AND_DISK_SER策略,而不是MEMORY_AND_DISK策略。因为 既然到了这一步,就说明RDD的数据量很大,内存无法完全放下。序列化后的数据比较少,可以节省内存和磁盘的空间开销。同时该策略会优先尽量尝试将数据缓 存在内存中,内存缓存不下才会写入磁盘。
- 通常不建议使用DISK_ONLY和后缀为_2的级别:因为完全基于磁盘文件进行数据的读写,会导致性能急剧降低,有时还不如重新计算一次 所有RDD。后缀为_2的级别,必须将所有数据都复制一份副本,并发送到其他节点上,数据复制以及网络传输会导致较大的性能开销,除非是要求作业的高可用 性,否则不建议使用。
参考文章地址:http://lxw1234.com/archives/2016/05/661.htm
spark中的cache和persist的区别的更多相关文章
- Spark中cache和persist的区别
cache和persist都是用于将一个RDD进行缓存的,这样在之后使用的过程中就不需要重新计算了,可以大大节省程序运行时间. cache和persist的区别 基于Spark 1.6.1 的源码,可 ...
- RDD中cache和persist的区别
通过观察RDD.scala源代码即可知道cache和persist的区别: def persist(newLevel: StorageLevel): this.type = { if (storage ...
- 【原创】大叔问题定位分享(27)spark中rdd.cache
spark 2.1.1 spark应用中有一些task非常慢,持续10个小时,有一个task日志如下: 2019-01-24 21:38:56,024 [dispatcher-event-loop-2 ...
- spark中map和mapPartitions算子的区别
区别: 1.map是对rdd中每一个元素进行操作 2.mapPartitions是对rdd中每个partition的迭代器进行操作 mapPartitions优点: 1.若是普通map,比如一个par ...
- 015 在Spark中关于groupByKey与reduceByKey的区别
1.groupByKey的源代码 2.groupByKey的使用缺点 不使用groupByKey的主要原因:在大规模的数据下,数据分布不均匀的情况下,可能导致OOM 3.reduceByKey的源代码 ...
- RDD的Cache、Persist、Checkpoint的区别和StorageLevel存储级别划分
为了增强容错性和高可用,避免上游RDD被重复计算的大量时间开销,Spark RDD设计了包含多种存储级别的缓存和持久化机制,主要有三个概念:Cache.Persist.Checkout. 1.存储级别 ...
- 大数据学习day21-----spark04------1. 广播变量 2. RDD中的cache 3.RDD的checkpoint方法 4. 计算学科最受欢迎老师TopN
1. 广播变量 1.1 补充知识(来源:https://blog.csdn.net/huashetianzu/article/details/7821674) 之所以存在reduce side jo ...
- RDD中的cache() persist() checkpoint()
cache只有一个默认的缓存级别MEMORY_ONLY ,而persist可以根据StorageLevel设置其它的缓存级别. cache以及persist都不是action. 被重复使用的(但是)不 ...
- spark中map与mapPartitions区别
在spark中,map与mapPartitions两个函数都是比较常用,这里使用代码来解释一下两者区别 import org.apache.spark.{SparkConf, SparkContext ...
随机推荐
- 0014SpringBoot结合thymeleaf实现登录功能
该登录功能需要实现的需求如下: 1.输入用户名密码,如果验证通过,进入首页,并显示登录的用户名 2.如果验证不通过,则重新进入登录页面,并显示“用户名密码错误” 3.如果未经登录,不能直接访问首页等静 ...
- 在cmd运行窗口运行.py文件
步骤
- 【Java】聚合和组合的区别
组合:部分与整体是与生俱来的,部分的存在依赖于整体.比如人与人的某个器官,人一出生,器官就在,人死亡,器官也就没了意义. 聚合:你与你的电脑(或者其它物品),电脑是属于你的吧,但是你是一出生就拥有了电 ...
- 六、用DataContractSerialize类序列化XML
一.层次结构 基类:XmlObjectSerializer 派生类: DataContractSerializer NetDataContractSerializer DataContractJson ...
- 2019牛客暑期多校训练营(第九场)Knapsack Cryptosystem——哈希表&&二进制枚举
题意 有长度为 $n$($1\leq n\leq 36$)的数列,给出 $s$,求和为 $s$ 的子集,保证子集存在且唯一. 分析 答案肯定是来自左右半边两部分组成的. 如果我们用哈希表存一半,计算另 ...
- JZOJ 5870 地图
直接解释题解,记录一下.
- GreenPlum 锁表以及解除锁定
最近遇到truncate表,无法清理的情况,在master节点查看加锁情况,并未加锁这种情况极有可能是segment节点相关表加了锁,所以遇到这种情况除了排查master节点的锁,所有的segment ...
- 007_Python3 字符串
字符串是 Python 中最常用的数据类型.我们可以使用引号( ' 或 " )来创建字符串. 创建字符串很简单,只要为变量分配一个值即可. 例如: var1 = 'Hello World!' ...
- 【.Net设计模式系列】仓储(Repository)模式 ( 一 )
开篇 2016新年伊始,望眼过去,不知不觉在博客园已经注册8个月啦,由于最近忙于工作,博客迟迟没有更新.直到最近一直研究.Net设计模式,对一些模式有所感悟,故拿出自己的心得与大家分享,在接下来的所有 ...
- ubuntu16.04源码编译安装nginx1.14.2
1.下载nginx-1.14.2, 官网地址:nginx.org 2.解压nginx-1.14.2.tar.gz tar zxvf nginx-1.14.2.tar.gz 3.切到文件夹nginx-1 ...