一起学spark(12)-- 关于RDD和DataFrame 的缓存

(1)Rdd持久化

   当调用RDD的persist()或者cache()方法时,这个RDD的分区会被存储到缓存区中,Spark会根据spark.storage.memoryFraction 限制用来缓存的内存占整个JVM堆空间的比例大小,如果超出限制,旧的分区数据会被移出内存。

   Spark默认的 cache() 操作会以MEMORY_ONLY 的存储等级持久化数据,意味着缓存新的RDD分区时空间不够,旧的分区就会丢失,当用到这些分区时,再根据血统进行重算。

   但persis()可以以MEMORY_AND_DISK 存储,内存中放不下的旧分区会写入磁盘,当再次需要时再从磁盘上读取回来,因此带来更稳定的性能表现。

'''导入 StorageLevel '''
from pyspark.storagelevel import StorageLevel

1.仅内存缓存,Spark将RDD作为为序列化的Java对象存储于内存中。语句如下

my_rdd.cache()
my_rdd.persist() #默认就是内存
my_rdd.persist(StorageLevel.MEMORY_ONLY)

序列化形式:以序列化的Java对象存储在内存,比未序列化在空间上利用更高,因为数据更紧凑。缺点是占用更多的CPU,因为对象在每次读写时都会做序列化/反序列化。当缓存RDD时,所选择的序列化器很重要。

my_rdd.persist(StorageLevel.MEMORY_ONLY_SER)

2.存于内存和磁盘:无法完全放入内存的分区溢写到磁盘

my_rdd.persist(StorageLevel.MEMORY_AND_DISK)
my_rdd.persist(StorageLevel.MEMORY_AND_DISK_SER) #序列化

3.仅存于磁盘,但CPU负载极高

my_rdd.persist(StorageLevel.DISK_ONLY)

4.堆外存储,在这种情况下,序列化的RDD将保存在Tachyon的堆外存储上,这个选项有很多好处,最重要的一个好处是可以在executor及其他应用之间共享一个内存池,减少垃圾回收带来的消耗。

my_rdd.persist(StorageLevel.OFF_HEAP)

如果应用程序是用Python写的,则不管是否选择了序列化的存储级别,RDD总是序列化的。

如果要从缓存中移除RDD,要么等着它以最近最久未使用(LRU)方式被消除,要么调用unpersist()方法

my_rdd.unpersist()

 

(2)SparkSQL 缓存

SparkSQL缓存的表是以列式存储在内存中的,使得在做查询时,不需要对整个数据集进行全部扫描,仅需要对需要的列进行扫描,所以性能有很大提升。

如果数据是以列式存储的,SparkSQL就能按列自动选择最优的压缩编码器,对它调优以减少内存使用及垃圾回收压力。DataFrame本身也是rdd,所以其实也可以直接按rdd的缓存方式缓存DataFrame

dataFrame.persist() #直接缓存dataFrame
#建议采用以下方式缓存
dataFrame.registerTempTable("tab_name")
hiveCtx.cacheTable("tab_name")

RDD持久化在执行action操作时才会被持久化,而SparkSQL中缓存表则在请求表时被缓存。

为释放内存,需要手动从缓存中删除表

dataFrame.unpersist()
hiveCtx.uncacheTable("tab_name") #基于cacheTable 方法

 

 

  • 3
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值