Spark缓存数据的替换和回收方法

Spark缓存数据的替换和回收方法

数据缓存的替换和回收是一个传统问题,如CPU中的多级缓存,页面替换机制。常见的缓存替换算法:FIFO(First Input First Output)先进先出、LRU(Least Recently Used)最近最久未被使用、MRU(Most Recently Used)最近最常被使用。

Spark中采用的替换原则是LRU替换算法,决定一个RDD是否要被替换的权衡之计是根据 cached RDD的访问历史判断,这种方式可能替换掉后续还会使用的RDD。

替换空间:如果需要缓存某个RDD,那么会在计算过程中对其进行缓存,每计算一个record就进行一次存储。正是由于Spark的缓存机制,我们无法预知RDD需要多大的缓存空间,无法判断需要替换多少个旧的RDD。因此Spark采用动态替换策略,每次通过LRU替换一个或多个RDD,然后开始存储新的RDD,如果中途存放不下,暂停进程,继续使用LRU替换一个或多个RDD,以此类推,直到存放完新的RDD。如果替换掉所有旧的RDD都存不下新的RDD,此时需要分为两种情况处理:如果新的RDD的存储级别里包含磁盘,此时可以将新的RDD存放到磁盘中;如果新的RDD的存储级别只是内存,那么就OOM。

Spark LRU算法的实现

Spark利用LinkedHashMap自带的LRU功能实现缓存替换。LinkedHashMap使用双向链表,每当Spark插入或读取其中的RDD分区数据时,LinkedHashMap自动调整链表结构,将最近插入或最近被读取的分区数据放在表头,这样链表尾部的分区数据就是最近最久未被访问的分区数据,替换时直接将链表维度的分区数据删除。因此,LinkedHashMap本身就形成了一个LRU cache。LinkedHashMap中的Key存放blockId(blockId=rdd_0_1表示rdd0的第2个分区)。

在进行缓存替换时,RDD的分区数据不能被该RDD的其他分区数据替换。即缓存替换前,要判断rdd的编号。

用户主动回收缓存数据

使用unpersist()操作,用户可以自己设置回收的RDD和回收时间。persist()是延时生效,完成所有计算才进行缓存,unpersist()操作时立即生效。用户还可以设定unpersisit()是同步阻塞还是异步执行,如unpersist(blocking-true)表示同步阻塞,即程序需要等待unpersist()结束后再使用下一步操作,这也是Spark的默认设定,而unpersisit(blocking=false)表示异步执行,即可以变执行unpersisit()边进行下一步操作。

与Hadoop MapReduce的缓存机制对比

Hadoop mapReduce的DistributedCache缓存机制,但不是用于存放中间结果的,而是用户缓存job运行所需的文件的,如所需的jar文件,每个map task需要读取的辅助文件、一些文本文件等。而且DistributedCache将缓存文件存放在每个worker的本地磁盘上,并不是内存中。Spark job一般包含多个操作,按照DAG图方式执行,也适用于迭代型应用,因此会产生大量中间数据和可复用数据,Spark为只写数据设计了基于内存和磁盘的缓存机制,可以更好地加速应用执行。

Spark当前的缓存机制的缺陷:缓存的RDD数据是只读的,不能修改;当前的缓存机制不能根据RDD的生命水汽进行自动缓存替换;只能用在每个Spark应用内部,即缓存数据只能在job之间共享,应用之间不能共享缓存数据。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值