RDD之间进行相互迭代计算(Transformation的转换),当执行开启后,新RDD的生成,代表老RDD的消失。RDD的数据是过程数据,只在处理的过程中存在,一旦处理完成,就不见了。这个特性可以最大化的利用资源,老旧RDD没用了就从内存中清理,给后续的计算腾出内存空间。
例如上图,rd3被2次使用,第一次使用之后,其实RDD3就不存在了.第二次用的时候,只能基于RDD的血缘关系,从RDD1重新执行,构建出来RDD3,供RDD5使用。
上述的场景,肯定要执行优化,优化就是:RDD3如果不消失,那么RDD1→RDD2→RDD3这个链条就不会执行2次,或者更多次RDD的缓存技术:Spark提供了缓存API,可以让我们通过调用APl,将指定的RDD数据保留在内存或者硬盘上缓存的API。
#RDD3被2次使用,可以加入缓存进行优化
rdd3.cache()#缓存到内存中.
rdd3.persist(StorageLevel.MEMORY_ONLY) #仅内存缓存
rdd3.persist(StorageLevel.MEMORY_ONLY_2) #仅内存缓存,2个副本
rdd3.persist(StorageLevel.DISK_ONLY) #仅缓存硬盘上
rdd3.persist(StorageLeveL.DISK_ONLY_2) #仅缓存硬盘上,2个副本
rdd3.Dtrsist (StorageLevet.DISK_ONLY_3) #仅缓存硬盘上,3个副本
rdd3.per sist(StorageLeveL.MEMORY_AND_DISK) #先放内存,不够放硬盘
rdd3.persist(StorageLeve1.MEMORY_AND_DISK_2)#先放内存,不够放硬盘,2个副本
rdd3.persist(StorageLevel.OFF_HEAP) #堆外内存(系统内存)
#如上API,自行选择使用即可
#一般建议使用rdd3.persist(StorageLevel.MEMORY_AND_DISK)
#如果内存比较小的集群,建议使用rdd3.persist(StorageLevel.DISK_ONLY)或者就别用缓存了用CheckPoint
#主动清理缓存的API
rdd.unpersist()
RDD缓存特点
缓存技术可以将过程RDD数据,持久化保存到内存或者硬盘上。
但是,这个保存在设定上是认为不安全的,缓存的数据在设计上是认为有丢失风险的。所以,缓存有一个特点就是:其保留RDD之间的血缘(依赖)关系,一旦缓存丢失,可以基于血缘关系的记录,重新计算这个RDD的数据。
缓存如何丢失:在内存中的缓存是不安全的,比如断电\计算任务内存不足,把缓存清理给计算让路,硬盘中因为硬盘损坏也是可能丢失的。
RDD缓存的保存过程