Spark的存储级别

存储模块

存储级别 意义
NONE 不会保存任何的数据
DISK_ONLY 直接将RDD的Partition保存在该节点的Disk上
MEMORY_ONLY

将RDD的Partition对应的原生的java object对象保存在JVM中。如果RDD太大,导致部分Partition无法保存在内存中的话,那么这些Partition将不会被缓存,在需要的时候,会被重新计算。这是默认的存储级别。

MEMORY_ONLY_SER 将RDD的Partition序列化后的对象(每一个Partition占用一个字节数组)存储在JVM中。通常来说,这将比直接保存原始对象来说空间利用率更高。尤其是在使用fast serializer(快速序列化)时。但是在读取的时候,由于需要进行反序列化,所以会占用一定量的CPU
MEMORY_AND_DISK 将RDD的partition反序列化后存储在JVM中,如果它的RDD太大,导致它的部分Partition不能存储在内存中,超出的Partition将会被保存在DISK上,需要的时候进行读取。
MEMORY_AND_DISK_SER 与MEMORY_ONLY_SER类似,但是会把超出内存的Partition保存在Disk上,而不是每次需要的时候重新计算。

DISK_ONLY_2

MEMORY_ONLY_2

MEMORY_ONLY_SER_2

MEMORY_AND_DISK_2

MEMORY_AND_DISK_SER_2

同上述的存储级别,不同的是在其他节点上会保存一个相同的备份。也就是说,从集群角度来看的话,会有两个备份。
OFF_HEAP(experimental)

堆外内存。

将RDD的Partition序列化后存储在堆外内存中(Tachyon),相比于MEMEORY_ONLY_SER,OFF_HEAP有以下几个优势:

  1. 减少GC带来的性能损耗
  2. 使得Executor的内存使用更加轻量级
  3. 在集群的角度共享一个内存池,非常有利于对内存有超大需求的Application;而且使得在多个Executor之间共享内存数据成为可能。


存储级别的选择

spark不同的存储级别是内存使用和CPU效率的折中。根据spark的官网建议,按照以下步骤来选择合适的存储级别:

  1. 如果RDD和默认的存储级别有很好的契合,那么就无需任何的特殊设定。默认的存储级别是CPU使用率最高的选项,也是运算能够最快完成的选项。
  2. 如果需要减少内存的使用,可以使用MEMORY_ONLY_SER。但是这个时候需要选择一个合适的序列化方式,具体的序列化方式可以参考http://spark.apache.org/docs/latest/tuning.html#data-serialization。需要在空间使用和反序列化时所需要的CPU中做一个合适的选择。
  3. 尽量不要落到硬盘上,除非是计算逻辑非常的复杂,或者说是要从一个超大规模的数据集中过滤出一小缤纷数据。否则重新计算一个partition的速度可能和从硬盘上读取的性能差不多(这里考虑到出错的概率和写硬盘的开销,因此采用失败重算要比读硬盘持久化的数据要好)。
  4. 如果需要故障的快速恢复能力(比如使用spark来处理Web请求),那么可以考虑使用存储级别的多副本机制。实际上所有的存储级别都提供了Partition数据丢失时的重算机制,只不过有备份的话可以让Application直接使用副本而无需等待重新计算丢失的Partition数据。
  5. 如果集群中有大量的内存或者有很多的运行任务,则选择OFF_HEAP。OFF_HEAP具有以下的优势
    1. 它是的多个Executor可以共享一个内存池
    2. 它显著的减少了GC的开销
    3. 缓存在内存中的数据即使是产生它的Executor异常退出了也不会丢失。
posted @ 2020-02-03 15:38  郭小白  阅读(2501)  评论(0编辑  收藏  举报