Redis基于内存存储,然而内存非常珍贵且有限,所以Redis提供两个策略回收内存
过期删除策略
我们可以通过expire命令给Redis的key设置TTL(存活时间),当key过期后,Redis会将这个键值对删除。
redisDb结构
database结构体中,有两个Dict:一个用来记录key-value;另一个用来记录key-TTL。
任何判断key是否过期
当我们查询一个key时,先看这个key是否在过期字典中,如果不在,则肯定没过期,直接读取键值对。如果在,与当前系统时间对比是否过期,如果没过期,正常读取键值对。
三种策略
定时删除
在设置key的过期时间的同时设置一个定时事件,时间到达后这个事件自动删除key。
惰性删除
只有在访问到这个key时在过期字典中检测到了这个key过期了才删除。
定期删除
每隔一段时间在数据库中取出一定数量的key进行检测过期的key就删除。
Redis的策略
惰性删除+定期删除
1. 在访问到这个key并且过期就删除
2. 默认每隔10秒在数据库的所有数据中随机抽取20个key判断是否有过期的,若过期的超过5个,则进行抽取删除。
内存淘汰策略
当Redis内存使用达到上限时,自动挑取某些键值对进行删除以释放内存。
在64位系统中默认没有内存限制,在32位写入中默认3G
1. 不进行内存淘汰(默认)
noeviction,即使内存超出限制,也不淘汰内存,如果有新数据写入,就报错。
2. 进行内存淘汰
全部数据中筛选
- 随机淘汰任意键值 allkeys-random
- 淘汰最旧未使用的键值 allkeys-lru:随机抽取5个值,淘汰最近没使用的一个
-
淘汰最少使用的键值 allkeys-lfu
在可能过期的数据中筛选
- 随机淘汰设置了过期时间的键值 volatile-random
- 淘汰最早过期的键值 volatile-ttl
- 淘汰最旧没使用的键值 volatile-lru
-
淘汰最少使用的键值 volatile-lfu
LRU和LFU算法
Redsi为了节省内存,没有设置LRU队列,而是在Redis的对象结构体中添加了一个额外字段记录这个key最近一次访问的时间
同样,LFU也是在对象结构体中使用与LRU的同一个字段记录了访问频率和访问时间,访问时间距离越久远,访问次数越少,这个key越容易被淘汰。