相信经常使用Redis的童鞋经常遇到过一个问题,redis的key过期了,为什么内存没有被释放?
在使用 Redis 时,肯定经常使用 SET 命令,SET 除了可以设置 key-value 之外,还可以设置 key 的过期时间。
如果你想修改 key 的值,但只是单纯地使用 SET 命令,而没有加上过期时间的参数,那这个 key 的过期时间将会被擦除,故时间一长,就导致大量的数据永久保存在内存中。
惰性删除: 当读/写一个已经过期的key时,会触发惰性删除策略,判断key是否过期,如果过期了直接删除掉这个key
定时删除: 由于惰性删除策略无法保证冷数据被及时删掉,所以Redis会定期(默认每100ms)主动淘汰一批已过期的key.这里的一批只是部分过期key,所以可能会出现部分key已经过期但还没有被清理掉的情况,导致内存并没有被释放
既然这样那Redis到底有几种key淘汰策略?是否遇到过没有设置过期时间的key也被淘汰掉了?当Redis已用内存超过maxmemory限定时候,触发主动清理策略,主动清理策略4.0之前一共实现了6种淘汰机制,4.0后增加2中方式,总共8种,分3类
针对设置了过期时间的key做处理
volatile-ttl:在筛选时候,会针对设置了过期的键值对,根据过期时间的先后进行删除,越早过期的越先被删除
volatile-random:如名,在设置了过期时间的键值对中,随机删除
volatile-lru:使用LRU算法筛选设置了过期时间的键值对删除
volatile-lfu:使用LFU算法筛选设置了过期时间的键值对删除
针对所有key做处理
allkeys-random:从所有键值对中随机删除
allkeys-lru:使用LRU算法在所有数据中进行筛选删除
allkeys-lfu:使用LFU算法在所有数据中进行筛选删除
不做处理
noeviction:不删除任何数据,拒绝所有写入操作并返回客户端错误信息。此时只响应读操作
PS:LRU 同 LFU区别
LRU(least recently used最近最少使用的):淘汰很久没被访问的数据,以最近一次访问的时间为参考
LFU(least frequency used,最不经常使用):淘汰最近一段时间被访问次数最少的数据,以次数作为参考
大多数情况使用LRU,当存在大量热点缓存数据时候,LFU可能更好点