Redis缓存过期、内存淘汰策略


过期键的删除策略

  • 立刻删除

    立刻删除能保证内存中数据的最大新鲜度,因为它保证过期键会在过期后马上被删除,其所占用的内存也会随之释放。但是对CPU不友好,因为删除会占用CPU时间,这会产生大量的性能消耗,同时也会影响数据的读取操作。

  • 惰性删除

    数据达到过期时间,不立刻删除,等下次访问时判断是否过期,过期则删除。该方式的缺点是对内存不友好,如果这个过期键一直不被访问,其所占用的内存就不会释放。我们甚至可以将这种情况看作是一种内存泄漏,无用的数据占用了大量内存,而服务器却不会主动去释放。

  • 定期删除

    这种方式是上面两种策略的折中,每隔一段时间执行一次删除过期键操作,并通过限制删除操作执行时长和频率来减少对CPU时间的影响。

    周期性轮询Redis库中的时效性数据,采用随机抽查的策略,利用过期数据占比的方式控制删除额度。

    该方式的难点在确定删除操作执行的时长和频率:

    如果删除操作太频繁或执行时间太长,定期删除策略就会退化为立刻删除策略,以至于将CPU时间过多消耗在删除过期键上;

    如果删除操作太少或执行时间太短,定期删除策略又会和惰性删除策略一样,出现浪费内存的情况。


Redis内存设置

如果不设置Redis的最大内存大小或者设置最大内存大小为0,在64位操作系统下不限制内存大小(默认)

修改配置:

1
2
maxmemory <bytes>
maxmemory 1048576 # 1MB

一般推荐Redis设置内存为最大物理内存的四分之三

如果Redis内存达到了使用上限,无法再设置新key,会抛出OOM异常


内存淘汰策略

如果我们希望Redis内存达到上限后,仍能正常提供服务,那么它就需要使用对应的一些淘汰策略。

Redis支持的内存淘汰策略如下:

  • noeviction(默认)

    该策略对于写请求不再提供服务,会直接返回错误,当然排除del等特殊操作

  • allkeys-random

    从Redis中随机选取key进行淘汰

  • allkeys-lru

    使用LRU算法,从Redis中选取使用最少的key进行淘汰

  • allkeys-lfu

    使用LFU,从Redis中选取某段时间之内使用频次最少的key进行淘汰

  • volatile-random

    从Redis中设置了过期时间的key,进行随机淘汰

  • volatile-ttl

    从Redis中选取即将过期的key,进行淘汰

  • volatile-lru

    使用LRU算法,从Redis设置了过期时间的key中,选取最少使用的key进行淘汰

  • volatile-lfu

    使用LFU算法,从Redis设置了过期时间的key中,选取某段时间之内使用频次最小的key进行淘汰

LRU:Least Recently Used,最近最少使用

淘汰最长时间未被使用的key,看key被使用到发生调度的时间长度

LFU:Least Frequently Used,最不经常使用

淘汰一定时期内被访问次数最少的key,看一段时间内key被使用的频率


性能优化建议:

  • 避免存储bigkey

  • 开启惰性淘汰

    1
    lazyfree-lazy-eviction yes