本文共 2250 字,大约阅读时间需要 7 分钟。
redis中缓存的数据是有过期时间的,当缓存数据失效时,redis会删除过期数据以节省内存,那redis是怎样怎样的策略来删除过期数据的呢?
过期删除策略通常有以下三种
其中前两种为主动删除策略,最后一种为被动删除策略。下面就来谈谈这三种策略的优缺点以及Redis中究竟使用的哪一种
定时删除策略对于内存来说十分友好,通过定时器能够保证过期键能够在第一时间被删除,而不会一直占用内存。
但是同样的,它对CPU时间非常不友好。在过期键比较多的时候,维护大量的定时器会给CPU带来巨大的压力,即使过期键少的时候,它也会将宝贵的CPU时间用在维护定时器,以及删除和当前任务无关的过期键上,对服务器的响应时间与吞吐量造成了一定的影响。
从开始的描述可以看出,惰性删除对于CPU时间来说是最为友好的,因为我们只会在取出键的时候才会对其进行删除操作,这也就保证了我们不会在执行其他任务的时候又背地里去删除无关的过期键,合理的利用了CPU时间。
但是!!!也正是因为这个原因,使得它对内存极度不友好。如果一个键已经过期,而只要我们不去获取这个键,就不会触发过期检查,那也就意味着他会一直占用这一块内存而不释放。
这意味着什么呢?如果我们有非常多的过期键,而这些过期键又恰好因为版本迭代、项目组交替,在后续版本中并没有对其进行访问,那么它可能永远也不会被删除。我们可以将这种情况当成内存泄漏中的一种,对于Redis这种内存数据库来说,这种情况造成的后果十分严重
定期删除策略其实是上述两种策略的折中选择。
定期删除策略相对于定时删除策略来说,由于其每隔一段时间才进行一次删除操作,通过限制了删除操作的时常和频率,大大减少了删除操作对CPU时间的影响。
相比于惰性删除,并且由于定期删除过期键,有效地减少了过期键带来的空间浪费。即兼顾了CPU,又避免了内存浪费,是两者的折中选择。
但是上述这些优点的前提,就是我们必须要确定一个合理的删除操作的时长和频率。
下面给出三种的效率对比
CPU:惰性删除 > 定期删除 > 定时删除
内存利用率:定时删除 > 定期删除 > 惰性删除
为了能够在合理利用CPU时间与避免浪费内存空间之间取得平衡,Redis同时使用了惰性删除和定期删除。
这样的搭配虽然保证了Redis强大的吞吐量以及响应速度,但是却存在因为没有定时删除机制,所以存在着内存浪费问题。
由于Redis中通常存储的数据量十分庞大,这就导致了定期删除每次只能抽取其中的一部分进行删除,倘若有一部分过期键一直没有被抽取到,并且我们也一直没有访问它来触发惰性删除,这个过期键就会一直存在内存中,如果不进行处理,就可能导致内存耗尽。
为了解决这个问题,Redis又引入了内存淘汰机制
当Redis的内存占用过高时,如果内存不足以容纳新写入的数据,就会通过某种机制来删除一部分键,来减少当前占用的内存,这就是内存淘汰机制。
当前Redis提供了8种内存淘汰策略,除却之前的6种,还有两种Redis4.0后新增的LFU模式:volatile-lfu以及allkeys-lfu
名称 | 作用 |
---|---|
volatile-lru | 在已设置过期时间的key中 ,挑选最近最少使用 的key淘汰 |
volatile-lfu | 在已设置过期时间的key中 ,挑选最不经常 使用的key淘汰 |
volatile-ttl | 在已设置过期时间的key中 ,挑选将要过期 的key淘汰 |
volatile-random | 在已设置过期时间的key中 ,随机挑选 key淘汰 |
allkeys-lru | 在所有key中 ,挑选最近最少使用 的key淘汰 |
allkeys-lfu | 在所有key中 , 挑选最不经常 使用的key淘汰 |
allkeys-random | 在所有key中 ,随机挑选 key淘汰 |
no-eviction | 当内存不足以写入新数据时,写入操作会报错,并且不会淘汰数据 (不常用) |
乍一看策略很多很难记,其实总共就是四种不同的淘汰策略,以及两种key的选择范围
选择范围
淘汰策略
其中LRU和LFU较为常用,如果有想了解其算法原理的,可以看看我的往期博客
转载地址:http://ldmsz.baihongyu.com/