您的位置:首页 > 其它

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

2018-02-07 18:05 363 查看
(1)Rdd持久化
   当调用RDD的persist()或者cache()方法时,这个RDD的分区会被存储到缓存区中,Spark会根据spark.storage.memoryFraction 限制用来缓存的内存占整个JVM堆空间的比例大小,如果超出限制,旧的分区数据会被移出内存。
   Spark默认的 cache() 操作会以MEMORY_ONLY 的存储等级持久化数据,意味着缓存新的RDD分区时空间不够,旧的分区就会丢失,当用到这些分区时,再根据血统进行重算。
   但persis()可以以MEMORY_AND_DISK 存储,内存中放不下的旧分区会写入磁盘,当再次需要时再从磁盘上读取回来,因此带来更稳定的性能表现。
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的缓存方式缓存DataFramedataFrame.persist() #直接缓存dataFrame
#建议采用以下方式缓存
dataFrame.registerTempTable("tab_name")
hiveCtx.cacheTable("tab_name")RDD持久化在执行action操作时才会被持久化,而SparkSQL中缓存表则在请求表时被缓存。为释放内存,需要手动从缓存中删除表dataFrame.unpersist()
hiveCtx.uncacheTable("tab_name") #基于cacheTable 方法
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  rdd持久化 spark