RDD的缓存

概述程序员

相比Hadoop MapReduce来讲,Spark计算具备巨大的性能优点,其中很大一部分缘由是Spark对于内存的充分利用,以及提供的缓存机制。apache

RDD持久化(缓存)数组

持久化在早期被称做缓存(cache),但缓存通常指将内容放在内存中。虽然持久化操做在绝大部分状况下都是将RDD缓存在内存中,但通常都会在内存不够时用磁盘顶上去(比操做系统默认的磁盘交换性能高不少)。固然,也能够选择不使用内存,而是仅仅保存到磁盘中。因此,如今Spark使用持久化(persistence)这一更普遍的名称。缓存

若是一个RDD不止一次被用到,那么就能够持久化它,这样能够大幅提高程序的性能,甚至达10倍以上。框架

默认状况下,RDD只使用一次,用完即扔,再次使用时须要从新计算获得,而持久化操做避免了这里的重复计算,实际测试也显示持久化对性能提高明显,这也是Spark刚出现时被人称为内存计算框架的缘由函数

假设首先进行了RDD0→RDD1→RDD2的计算做业,那么计算结束时,RDD1就已经缓存在系统中了。在进行RDD0→RDD1→RDD3的计算做业时,因为RDD1已经缓存在系统中,所以RDD0→RDD1的转换不会重复进行,计算做业只须进行RDD1→RDD3的计算就能够了,所以计算速度能够获得很大提高。oop

持久化的方法是调用persist()函数,除了持久化至内存中,还能够在persist()中指定storage level参数使用其余的类型,具体以下:性能

 

1MEMORY_ONLY : 将 RDD 以反序列化的 Java 对象的形式存储在 JVM 中. 若是内存空间不够,部分数据分区将不会被缓存,在每次须要用到这些数据时从新进行计算. 这是默认的级别。测试

 

cache()方法对应的级别就是MEMORY_ONLY级别加密

 

2MEMORY_AND_DISK:将 RDD 以反序列化的 Java 对象的形式存储在 JVM 中。

若是内存空间不够,将未缓存的数据分区存储到磁盘,在须要使用这些分区时从磁盘读取。

 

3MEMORY_ONLY_SER :将 RDD 以序列化的 Java 对象的形式进行存储(每一个分区为一个 byte 数组)。这种方式会比反序列化对象的方式节省不少空间,尤为是在使用 fast serialize时会节省更多的空间,可是在读取时会使得 CPU 的 read 变得更加密集。若是内存空间不够,部分数据分区将不会被缓存,在每次须要用到这些数据时从新进行计算。

 

4MEMORY_AND_DISK_SER :相似于 MEMORY_ONLY_SER ,可是溢出的分区会存储到磁盘,而不是在用到它们时从新计算。若是内存空间不够,将未缓存的数据分区存储到磁盘,在须要使用这些分区时从磁盘读取。

 

5DISK_ONLY:只在磁盘上缓存 RDD。

 

6MEMORY_ONLY_2, MEMORY_AND_DISK_2, etc. :与上面的级别功能相同,

只不过每一个分区在集群中两个节点上创建副本。

 

7)OFF_HEAP 将数据存储在 off-heap memory 中。使用堆外内存,这是Java虚拟机里面的概念,堆外内存意味着把内存对象分配在Java虚拟机的堆之外的内存,这些内存直接受操做系统管理(而不是虚拟机)。使用堆外内存的好处:可能会利用到更大的内存存储空间。可是对于数据的垃圾回收会有影响,须要程序员来处理

注意,可能带来一些GC回收问题

Spark 也会自动持久化一些在 shuffle 操做过程当中产生的临时数据(好比 reduceByKey),即使是用户并无调用持久化的方法。这样作能够避免当 shuffle 阶段时若是一个节点挂掉了就得从新计算整个数据的问题。若是用户打算屡次重复使用这些数据,咱们仍然建议用户本身调用持久化方法对数据进行持久化。

 

使用缓存

scala> import org.apache.spark.storage._

scala> val rdd1=sc.makeRDD(1 to 5)

scala> rdd1.cache  //cache只有一种默认的缓存级别,即MEMORY_ONLY

scala> rdd1.persist(StorageLevel.MEMORY_ONLY)

缓存数据的清除

Spark 会自动监控每一个节点上的缓存数据,而后使用 least-recently-used (LRU) 机制来处理旧的缓存数据。若是你想手动清理这些缓存的 RDD 数据而不是去等待它们被自动清理掉,

可使用 RDD.unpersist( ) 方法。

相关文章
相关标签/搜索