RDD缓存机制

1. 目的

本节将介绍什么是RDD缓存,RDD缓存策略,Spark中的cache()和persist()方法之间的区别,如何删除缓存。

2. 什么是RDD缓存

RDD缓存是一种优化技术,是Spark速度非常快的原因之一。当缓存某个RDD后,每一个节点都将把计算分区结果保存在内存中,对此RDD或衍生出的RDD进行的其他动作中重用。这使得后续的动作变得更加迅速。缓存是Spark构建迭代式算法和快速交互式查询的关键。

RDD通过persist方法或cache方法可以将前面的计算结果缓存,但是并不是这两个方法被调用时立即缓存,而是触发后面的action时,该RDD将会被缓存在计算节点的内存中,并供后面重用。缓存有可能丢失,或者存储于内存的数据由于内存不足而被删除,RDD的缓存容错机制保证了即使缓存丢失也能保证计算的正确执行。通过基于RDD的一系列转换,丢失的数据会被重算,由于RDD的各个Partition是相对独立的,因此只需要计算丢失的部分即可,并不需要重算全部Partition。

3. RDD缓存策略

Spark 为持久化RDD定义了几种不同的机制,用不同的 StorageLevel 值表示。

Storage Level

MEMORY_ONLY 将RDD作为非序列化的对象存储在JVM中。如果RDD不能被内存装下,一些分区将不会被缓存,并且在需要的时候被重新计算。这是系统默认的存储级别。

MEMORY_ONLY_SER 将RDD作为序列化的对象存储(每个分区一个byte数组)。这种方式比非序列化方式更节省空间,特别是用到快速的序列化工具时,但是会更耗费CPU资源。

MEMORY_AND_DISK 将RDD作为非序列化的对象存储在JVM中。如果RDD不能被与内存装下,超出的分区将被保存在硬盘上,并且在需要时被读取。

MEMORY_AND_DISK_SER 和MEMORY_ONLY_SER类似,但不是在每次需要时重复计算这些不适合存储到内存中的分区,而是将这些分区存储到磁盘中。

DISK_ONLY 仅仅将RDD分区存储到磁盘中。

MEMORY_ONLY_2, MEMORY_AND_DISK_2, etc. 和上面的存储级别类似,但是复制每个分区到集群的两个节点上。

4. cache()和persist()之间的区别

RDD.cache()是RDD.persist(StorageLevel.MEMORY_ONLY) 的简写,它将 RDD 存储为未序列化的对象,而persist()可以根据情况设置其它的缓存级别。当 Spark 估计内存不够存放一个分区时,它干脆就不在内存中存放该分区,这样在下次需要时就必须重新计算。在对象需要频繁访问或低延访问时适合使用StorageLevel.MEMORY_ONLY。相比其他选项, StorageLevel.MEMORY_ONLY 的问题是要占用更大的内存空间。另外,大量小对象会对 JVM的垃圾回收造成压力,会导致程序停顿。

一般情况下,如果多个动作需要用到某个 RDD,而它的计算代价又很高,那么就应该把这个 RDD 缓存起来。

5. 如何删除缓存

Spark会自动监控每个节点的缓存,并以LRU(最近最少使用)的方式删除缓存。我们也可以使用RDD.unpersist()方法手动删除缓存。

RDD缓存机制
滚动到顶部