摘要
众所周知,redis的性能强,最主要的原因是基于内存存储,但是内存资源是有限且宝贵的,除了我们手动设置内存存储上限和过期时间,但存储的数据达到一定的量的时候,redis会按照内存淘汰策略进行淘汰数据。本文针对过期key的回收和redis提供的内存淘汰策略进行详细的探讨。
过期key的处理
在redis的数据库中存在两张dict表,一张用来存储key,value数据,一张用于存储key对应的过期时间。
清理过期key存在两种策略。redis会同时使用这两种策略
一、惰性删除:
当客户端在访问某一个key时,redis会检查存储key对应过期时间的表,如果该key已经过期,则进行删除。也就是说,如果没有访问一个过期的key,它仍然存储在database中。
- 优点:CPU友好
- 缺点:内存不友好,过期key仍有可能占用 内存
二、周期性删除:
通过设置一个定时任务,周期性的抽取部分key进行检查,如果过期则进行删除。
执行的周期也分SLOW和FAST模式。
SLOW模式:按照server.hz的频率来执行过期key的清理,每秒执行server.hz次,默认情况下server.hz为10。并且每次清理过程不超过25ms。
FAST模式:在每个事件循环前会调用beforeSleep()函数,执行过期key清理。
redis内存淘汰策略
当redis使用的内容达到上限时,redis会主动清理一下key以释放内存。
Redis支持8种不同策略来选择要删除的key:
- 全体key
- 随机淘汰 allkeys-random
- 基于LRU进行淘汰 allkeys-lru
- 基于LFU进行淘汰 allkeys-lfu
- 不淘汰,拒绝写入新数据(默认策略) no-eviction
- 设置了TTL的key
- 随机淘汰 volatile-random
- 基于LRU进行淘汰 volatile-lru
- 基于LFU进行淘汰 volatile-lfu
- 优先淘汰TTL小的key volatile-ttl
补充:
- LRU(Least Recently Used),最少最近使用。用当前时间减去最后一次访问时间,这个值越大则淘汰优先级越高。
- LFU(Least Frequently Used),最少频率使用。会统计每个key的访问频率,值越小淘汰优先级越高。