RDD通过persist方法或cache方法可以将前面的计算结果缓存,但是并不是这两个方法被调用时立即缓存,而是触发后面的action时,该RDD将会被缓存在计算节点的内存中,并供后面重用。
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, 2)
val MEMORY_ONLY = new StorageLevel(false, true, false, true)
val MEMORY_ONLY_2 = new StorageLevel(false, true, false, true, 2)
val MEMORY_ONLY_SER = new StorageLevel(false, true, false, false)
val MEMORY_ONLY_SER_2 = new StorageLevel(false, true, false, false, 2)
val MEMORY_AND_DISK = new StorageLevel(true, true, false, true)
val MEMORY_AND_DISK_2 = new StorageLevel(true, true, false, true, 2)
val MEMORY_AND_DISK_SER = new StorageLevel(true, true, false, false)
val MEMORY_AND_DISK_SER_2 = new StorageLevel(true, true, false, false, 2)
val OFF_HEAP = new StorageLevel(false, false, true, false)
......
}
class StorageLevel private(
private var _useDisk: Boolean,
private var _useMemory: Boolean,
private var _useOffHeap: Boolean,
private var _deserialized: Boolean,
private var _replication: Int = 1)
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提供的一种机制,将对象表示成一连串的字节;而反序列化就表示将字节恢复为对象的过程。序列化是对象永久化的一种机制,可以将对象及其属性保存起来,并能在反序列化后直接恢复这个对象。序列化方式存储对象可以节省磁盘或内存的空间,一般 序列化:反序列化=1:3 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 类的源码中有一段代码可以看出这个的特殊性,它不能和其它几个参数共存。
rdd.cache操作 rdd.persist操作,通过这两个操作就能够缓存RDD的数据
rdd缓存操作也是懒加载的,也是有action算子进行触发
rdd数据缓存以后,后续在使用这个RDD的时候其运行速度要比第一次rdd创建时候速度要快至少10倍
rdd.cache与 rdd.persist区别
cache和persist实际上是一个方法 都是调用的 persist(StorageLevel.MEMORY_ONLY)
RDD的缓存级别
总共12中缓存级别
//不使用缓存
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, 2)
//缓存到内存当中 默认常用
val MEMORY_ONLY = new StorageLevel(false, true, false, true)
//缓存到内存当中并且备份
val MEMORY_ONLY_2 = new StorageLevel(false, true, false, true, 2)
//缓存到内存当中并且序列化
val MEMORY_ONLY_SER = new StorageLevel(false, true, false, false)
//缓存到内存当中并且序列化 备份
val MEMORY_ONLY_SER_2 = new StorageLevel(false, true, false, false, 2)
//缓存到内存当中和磁盘 常用
val MEMORY_AND_DISK = new StorageLevel(true, true, false, true)
//缓存到内存当中和磁盘 备份
val MEMORY_AND_DISK_2 = new StorageLevel(true, true, false, true, 2)
//缓存到内存当中和磁盘 序列化 常用
val MEMORY_AND_DISK_SER = new StorageLevel(true, true, false, false)
//缓存到内存当中和磁盘 序列化 备份
val MEMORY_AND_DISK_SER_2 = new StorageLevel(true, true, false, false, 2)
//堆外内存
val OFF_HEAP = new StorageLevel(true, true, true, false, 1)
释放资源rdd.unpersist
RDD的缓存机制有没有缺点:
RDD使用内存和磁盘缓存,使用内存可能会被JVM垃圾回收。使用磁盘可能会损坏或者被人为删除掉。
原文:https://www.cnblogs.com/tshcj/p/12370646.html