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