一、Redis的过期策略
策略: Redis采用的是定期删除+惰性删除策略。
1.1 方式:
定期删除
redis默认每隔100ms就随机抽取一些设置了过期时间的key,检测这些key是否过期,如果过期了就将其删掉。
PS:Redis不是每隔100ms将所有的key检查一次,而是随机抽取进行检查。因为如果这是redis里面有大量的key都设置了过期时间,那么如果全部去检测一遍,CPU负载就会很高,会浪费大量的时间在检测上面,甚至直接导致redis挂掉。所有只会抽取一部分而不会全部检查。
因此,如果只采用定期删除策略,就会出现大量的已经过期的key并没有被删除,这就是 为什么有时候大量的key明明已经过了失效时间,但是redis的内存还是被大量占用的原因。
惰性删除
在获取某个key的时候,redis会先去检测一下这个key是否已经过期,如果没有过期则返回给你,如果已经过期了,那么redis会删除这个key,不会返回。
1.2 新问题
如果定期删除没删除key。也没发生该key的请求,即惰性删除也没生效。这种方式下redis的内存会越来越高。因此还需要采用内存淘汰机制来进一步保障。
上述两种策略保证了过期的key最终一定会被删除掉 ,但是这只是保证了最终一定会被删除。要是定时删除漏掉了大量过期的key,而且也没有去访问这些key,那么这些key会一直存在下去,最终导致redis内存耗尽。
由于存在这样的问题,所以redis引入了 内存淘汰机制 来解决。
二、数据(内存)淘汰机制策略
2.1、LRU算法
LRU算法的淘汰过程模拟:
- 假设将内存空间划分为3个区域。
- step1: 最开始时,内存空间是空的,因此依次进入A、B、C是没有问题的。
- step2: 当加入D时,就出现了问题,内存空间不够了,因此根据LRU算法,内存空间中A待的时间最为久远,选择A,将其淘汰。
- step3: 当某个服务再次引用或使用B时,内存空间中的B又处于活跃状态,而C则变成了内存空间中近段时间最久未使用的数据。
- step4: 当再次向内存空间加入E时,这时内存空间又不足了,选择在内存空间中待的最久的C将其淘汰出内存,这时的内存空间存放的对象就是E->B->D。
2.2. Redis中的LRU算法配置
redis.conf 配置文件: # maxmemory-policy allkeys-lru
2.3 redis提供了6种内存淘汰策略
noeviction:当内存不足以容纳新写入数据时,新写入操作会报错,无法写入新数据,一般不采用。
allkeys-lru:当内存不足以容纳新写入数据时,在键空间中,移除最近最少使用的key。最常用的。推荐使用。
allkeys-random:当内存不足以容纳新写入数据时,在键空间中,随机移除某个key。一般不使用。
volatile-lru:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,移除最近最少使用的key。这种情况一般是把redis既当缓存,又做持久化存储的时候才用。不推荐。
volatile-random:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,随机移除某个key。不推荐。
volatile-ttl:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,有更早过期时间的key优先移除。不推荐。