持久化
-
在java中,把数据写入数据库的过程
-
在spark中,把RDD临时永久地写入到节点地某个位置(磁盘或内存)
永久:避免当前RDD被当作垃圾回收掉,对其永久保存
临时:即使做了持久化,在内存中也不是绝对地安全
a.由于某种特殊情况,会被当作垃圾回收掉
b.没有意外情况下,根据LRU也会被当作垃圾回收掉
-
容错机制
如果持久化的数据丢失了,spark会自动从HDFS上找数据重新计算到这个位置,自动持久化。
-
使用
缓存算子:
cache persist
这两个算子完全等价
相当于使用了默认的的仅用内存的持久化策略
RDD.cache() / persist()
RDD.persist(StorageLevel.XXX)
移除持久化:
a.根据LRU自动取消持久化
b.RDD.unpersist()
-
验证:
a.webUI http://ip:4040 -> storage
b.RDD.getStorageLevel 以StorageLevel对象的类型返回
RDD.getStorageLevel.describe 以字符串类型返回
策略
(1) MEMORY_ONLY 与 MEMORY_AND_DISK对比
MEMORY_ONLY:先可内存存储,存不下就不存了。读取数据的时候先读内存,没有持久化的部分从HDFS重
新计算
MEMORY_AND_DISK:先可内存存储,如果存不下,就存磁盘
总结:
作者认为,即使从hdfs重新计算也比多做一次磁盘IO速度快
使用场景:
-
如果没有特殊情况,直接使用默认的存储等级
这种情况可以使用CPU发挥最大的性能
-
如果内存不太充足,可以选择SER,节省一定的空间
由于还是内存计算,速度也会快,但是读取的时候需要反序列化
-
除非计算很复杂不要使用DISK
重新计算的耗时与做磁盘IO差不多甚至更多,可以选择此方式
-
如果想做快速恢复可以使用带副本的形式
虽然可以自动容错,但是重新计算需要时间
checkPoint()
-
把当前RDD可以标记成一个检查点
-
把当前RDD的最终状态保存到一个目录中,目录由sc.setCheckPointDir设置
-
会移除当前RDD的所有父级依赖的引用,它成为了顶级依赖
-
这是个转换算子,必须在行动算子之前调用
-
强烈建议在检查点之前先设置persist,避免重复计算