cache和persist都是用于将一个RDD进行缓存的,这样在之后使用的过程中就不需要重新计算了,可以大大节省程序运行时间。

cache和persist的区别

基于Spark 1.6.1 的源码,可以看到

/** Persist this RDD with the default storage level (`MEMORY_ONLY`). */
def cache(): this.type = persist()

说明是cache()调用了persist(), 想要知道二者的不同还需要看一下persist函数:

/** Persist this RDD with the default storage level (`MEMORY_ONLY`). */
def persist(): this.type = persist(StorageLevel.MEMORY_ONLY)

可以看到persist()内部调用了persist(StorageLevel.MEMORY_ONLY),继续深入:

/**
* 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..
*/
def persist(newLevel: StorageLevel): this.type = {
// TODO: Handle changes of StorageLevel
if (storageLevel != StorageLevel.NONE && newLevel != storageLevel) {
throw new UnsupportedOperationException(
"Cannot change storage level of an RDD after it was already assigned a level")
}
sc.persistRDD(this)
// Register the RDD with the ContextCleaner for automatic GC-based cleanup
sc.cleaner.foreach(_.registerRDDForCleanup(this))
storageLevel = newLevel
this
}

可以看出来persist有一个 StorageLevel 类型的参数,这个表示的是RDD的缓存级别。

至此便可得出cache和persist的区别了:cache只有一个默认的缓存级别MEMORY_ONLY ,而persist可以根据情况设置其它的缓存级别。

RDD的缓存级别

顺便看一下RDD都有哪些缓存级别,查看 StorageLevel 类的源码:

object StorageLevel {
val NONE = new StorageLevel(false, false, false, false)
val DISK_ONLY = new StorageLevel(true, false, false, false)
val DISK_ONLY_2 = new StorageLevel(true, false, false, false, )
val MEMORY_ONLY = new StorageLevel(false, true, false, true)
val MEMORY_ONLY_2 = new StorageLevel(false, true, false, true, )
val MEMORY_ONLY_SER = new StorageLevel(false, true, false, false)
val MEMORY_ONLY_SER_2 = new StorageLevel(false, true, false, false, )
val MEMORY_AND_DISK = new StorageLevel(true, true, false, true)
val MEMORY_AND_DISK_2 = new StorageLevel(true, true, false, true, )
val MEMORY_AND_DISK_SER = new StorageLevel(true, true, false, false)
val MEMORY_AND_DISK_SER_2 = new StorageLevel(true, true, false, false, )
val OFF_HEAP = new StorageLevel(false, false, true, false)
......
}

可以看到这里列出了12种缓存级别,但这些有什么区别呢?可以看到每个缓存级别后面都跟了一个StorageLevel的构造函数,里面包含了4个或5个参数,如下

val MEMORY_ONLY = new StorageLevel(false, true, false, true)

查看其构造函数

class StorageLevel private(
private var _useDisk: Boolean,
private var _useMemory: Boolean,
private var _useOffHeap: Boolean,
private var _deserialized: Boolean,
private var _replication: Int = )
extends Externalizable {
......
def useDisk: Boolean = _useDisk
def useMemory: Boolean = _useMemory
def useOffHeap: Boolean = _useOffHeap
def deserialized: Boolean = _deserialized
def replication: Int = _replication
......
}

可以看到StorageLevel类的主构造器包含了5个参数:

  • useDisk:使用硬盘(外存)
  • useMemory:使用内存
  • useOffHeap:使用堆外内存,这是Java虚拟机里面的概念,堆外内存意味着把内存对象分配在Java虚拟机的堆以外的内存,这些内存直接受操作系统管理(而不是虚拟机)。这样做的结果就是能保持一个较小的堆,以减少垃圾收集对应用的影响。
  • deserialized:反序列化,其逆过程序列化(Serialization)是java提供的一种机制,将对象表示成一连串的字节;而反序列化就表示将字节恢复为对象的过程。序列化是对象永久化的一种机制,可以将对象及其属性保存起来,并能在反序列化后直接恢复这个对象
  • replication:备份数(在多个节点上备份)

理解了这5个参数,StorageLevel 的12种缓存级别就不难理解了。

val MEMORY_AND_DISK_SER_2 = new StorageLevel(true, true, false, false, 2) 就表示使用这种缓存级别的RDD将存储在硬盘以及内存中,使用序列化(在硬盘中),并且在多个节点上备份2份(正常的RDD只有一份)

另外还注意到有一种特殊的缓存级别

val OFF_HEAP = new StorageLevel(false, false, true, false)

使用了堆外内存,StorageLevel 类的源码中有一段代码可以看出这个的特殊性,它不能和其它几个参数共存。

if (useOffHeap) {
require(!useDisk, "Off-heap storage level does not support using disk")
require(!useMemory, "Off-heap storage level does not support using heap memory")
require(!deserialized, "Off-heap storage level does not support deserialized storage")
require(replication == , "Off-heap storage level does not support multiple replication")
}

Spark中cache和persist的区别的更多相关文章

  1. RDD中cache和persist的区别

    通过观察RDD.scala源代码即可知道cache和persist的区别: def persist(newLevel: StorageLevel): this.type = { if (storage ...

  2. spark中的cache和persist的区别

    在使用中一直知其然不知其所以然的地使用RDD.cache(),系统的学习之后发现还有一个与cache功能类似看起来冗余的persist 点进去一探究竟之后发现cache()是persist()的特例, ...

  3. Spark中ml和mllib的区别

    转载自:https://vimsky.com/article/3403.html Spark中ml和mllib的主要区别和联系如下: ml和mllib都是Spark中的机器学习库,目前常用的机器学习功 ...

  4. spark中map与flatMap的区别

    作为spark初学者对,一直对map与flatMap两个函数比较难以理解,这几天看了和写了不少例子,终于把它们搞清楚了 两者的区别主要在于action后得到的值 例子: import org.apac ...

  5. Spark中repartition和partitionBy的区别

    repartition 和 partitionBy 都是对数据进行重新分区,默认都是使用 HashPartitioner,区别在于partitionBy 只能用于 PairRDD,但是当它们同时都用于 ...

  6. Spark中groupBy groupByKey reduceByKey的区别

    groupBy 和SQL中groupby一样,只是后面必须结合聚合函数使用才可以. 例如: hour.filter($"version".isin(version: _*)).gr ...

  7. Linux中cache和buff的区别

    两者都是:缓冲区 cache是存在于cpu和内存之间的缓冲区,存放的是从disk上读取到的数据 buff是用于存放要输出到块存储的数据 清除缓冲的方法 [root@DD-Server-9F ~]# e ...

  8. RDD的Cache、Persist、Checkpoint的区别和StorageLevel存储级别划分

    为了增强容错性和高可用,避免上游RDD被重复计算的大量时间开销,Spark RDD设计了包含多种存储级别的缓存和持久化机制,主要有三个概念:Cache.Persist.Checkout. 1.存储级别 ...

  9. spark中map与mapPartitions区别

    在spark中,map与mapPartitions两个函数都是比较常用,这里使用代码来解释一下两者区别 import org.apache.spark.{SparkConf, SparkContext ...

随机推荐

  1. 《转载》Eclipse项目上传码云

    本文转载自http://blog.csdn.net/izzyliao/article/details/53074452 把Eclipse项目上传到码云的步骤: 1.登录码云:新建项目 2.输入项目名: ...

  2. JAVA知多少

    读<java解惑>感觉有意思的就记录一下. 1.判断奇数还是偶数 public boolean isOdd(int i){ return i%2==1; }; 这样子看起来很对,但是考虑到 ...

  3. Archive of all Android Studio releases / Eclipse 版本大全 / OpenJDK 各版本

    一 Android Studio 版本大全 https://developer.android.com/studio/archive.html Download Archives This is an ...

  4. 题目1440:Goldbach's Conjecture(哥达巴赫猜想)

    题目链接:http://ac.jobdu.com/problem.php?pid=1440 详解链接:https://github.com/zpfbuaa/JobduInCPlusPlus 参考代码: ...

  5. ELK系列二:Elasticsearch的架构原理和配置优化

    1.Elasticsearch的数据组织架构 1.1.Elasticsearch结构概念 集群(cluster):拥有相同cluster-name的elasticsearch结点的集合(每个结点其实就 ...

  6. 【BZOJ1502】[NOI2005]月下柠檬树 Simpson积分

    [BZOJ1502][NOI2005]月下柠檬树 Description 李哲非常非常喜欢柠檬树,特别是在静静的夜晚,当天空中有一弯明月温柔地照亮地面上的景物时,他必会悠闲地坐在他亲手植下的那棵柠檬树 ...

  7. 修改nose_html_reporting,解决输出带中文时,不能生成html文件

    在使用nose_html_reporting时,如果测试输出中带有中文,那么html输出会失败,提示如下: 提示'ascii'编码码失败 这是因为在string.IO中取回来的数据与当前脚本中声明的编 ...

  8. AngularJS初始(一)

    什么是AngularJs? angularjs是一个为动态WEB应用设计的结构框架.它能让你使用HTML作为模板语言,通过扩展HTML的语法,让你能更清楚.简洁地构建你的应用组件.它的创新点在于,利用 ...

  9. /etc/vim/vimrc的一个的配置

    (转)Vim 配置文件===/etc/vimrc "===================================================================== ...

  10. linux 安装Swagger(swagger-editor , swagger-ui)

    一.环境要求 1.Nodejs ( 版本6.0x以上 ) 2.npm (npm 3.x) 注: linux 更新nodejs到最新 node -v 4.2.1 sudo npm cache clean ...