RDD 的持久化
RDD的数据是过程数据,RDD之间相互迭代计算,新的RDD的生成代表旧的RDD的消失。
RDD的数据只在过程中存在,一旦处理完成,就会从内存中清除。
RDD1->RDD2->RDD3->RDD4(RDD4出现,RDD3就消失了)
\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ->RDD5(RDD5出现需要的RDD3需要从RDD1重新构建)
为了减少重复调用,引入缓存技术。
1.1 RDD的缓存
Spark提供了缓存API,我们可以调用API,将指定的RDD数据保存在内存或硬盘上。
# RDD3被二次调用,缓存以优化
rdd3.cache() # 缓存到内存中
rdd3.persist(StorageLevel.MEMORY_ONLY) # 仅缓存到内存中
rdd3.persist(StorageLevel.MEMORY_ONLY_2) # 仅缓存到内存中,两个副本
rdd3.persist(StorageLevel.DISK_ONLY) # 仅缓存到硬盘中
rdd3.persist(StorageLevel.DISK_ONLY_2) # 仅缓存到硬盘中,两个副本
rdd3.persist(StorageLevel.DISK_ONLY_3) # 仅缓存到硬盘中,三个副本
rdd3.persist(StorageLevel.MEMORY_AND_DISK) # 先放内存,不够放硬盘(建议使用)
rdd3.persist(StorageLevel.MEMORY_AND_DISK_2) # 先放内存,不够放硬盘,两个副本
rdd3.persist(StorageLevel.OFF_HEAP) # 境外内存(系统内存)
# 内存较小集群建议rdd3.persist(StorageLevel.DISK_ONLY) 或用 checkpoint
# 主动清理缓存
rdd3.unpersist()
缓存是分散存储的。
缓存是不安全的(设计上认为),缓存如果丢失,就要重新计算,即缓存要保留RDD的前置血缘关系。
1.2 RDD的CheckPoint
CheckPoint是集中收集各个分区的数据进行存储,可以集中放在HDFS中。
缓存和CheckPoint的对比:
- CheckPoint不管分区数多少,风险是一样的,缓存分区越多,风险越高
- CheckPoint支持写入HDFS,缓存不行,HDFS是高可靠存储,CheckPoint被认为是安全的
- CheckPoint不支持内存,缓存可以,缓存存储在内存性能好于CheckPoint
- CheckPoint因为设计认为是安全的,所以不保留血缘关系,而缓存在设计上认为不安全,所以保留
# 先设置checkpoint的保存路径
# 如果是locol模式,可以设置本地路径,集群则只支持hdfs
sc.setCheckPointDir("hdfs://后面跟上hdfs路径")
rdd.checkpoint()