Ch07-Spark 之缓存

Ch07-Spark 之缓存

May 31, 2019
Apache Spark
spark

Spark 的一个重要特性是能够把计算结果数据保存到内存或磁盘中,供后面的操作读取,这就是 RDD 的缓存,这个过程也可称为 persist 或 caching(Spark 提供了 persist()cache() 函数来缓存 RDD)。

1. persist #

persist() 函数只是对 RDD 的 storageLevel(存储级别)进行了设置,函数内部并没有执行任何数据缓存的动作。

  1. 在通过 RDD 的 iterator 读取 RDD 分区数据时,判断 RDD 的 storageLevel 变量,若该变量的值不是默认值 StorageLevel.NONE,则说明 storageLevel 的值已经被 persist 函数配置过。进入第 2 步。
  2. storageLevel 不为 StorageLevel.NONE,则首先从内存或磁盘中获取数据,此时会调用 BlockManager#get 函数根据 storageLevel 从内存或磁盘中获取数据块。若获取到了数据块则直接返回。没有从内存或磁盘获取到数据块,则需要计算数据块,进入第 3 步。
  3. 若从内存或磁盘中没有获取到数据,则需要计算该数据。计算完成后,会根据存储级别(storageLevel 的值)把计算出来的分区数据保存到内存或磁盘中,供下一次读取。

1.1 StorageLevel #

持久化级别 说明
MEMORY_ONLY 将 RDD 存储为 JVM 中的反序列化 Java 对象。如果 RDD 不存在内存时,则某些分区将不会被缓存,并且每次需要时都会重新计算。
MEMORY_AND_DISK 将 RDD 存储为 JVM 中的反序列化 Java 对象。如果 RDD 不适合保存在内存中,则可以保存在磁盘中,需要时可以从磁盘读取。
MEMORY_ONLY_SER 将 RDD 存储为 JVM 中的序列化 Java 对象。通常比反序列化对象更节省空间,特别是在使用快速序列化器时,但是读取 CPU 密集程度更高。
MEMORY_AND_DISK_SER 与 MEMORY_ONLY_SER 类似,但会将不适合内存的分区溢出到磁盘。而不是每次需要时在实时计算它们。
DISK_ONLY 仅将 RDD 分区存储在磁盘上。
MEMORY_ONLY_2MEMORY_AND_DISK_2 将 RDD 在其他节点上再保存一份,在数据丢失时,不需要再次计算。
OFF_HEAP RDD 存储在对外内存中。

2. cache #

def cache(): this.type = persist()