一、redis过期策略
当我们通过set命令保存某些数据的时候,可以指定过期时间,使缓存到时间后失效。但当redis中的key数量随着时间推移逐渐增长,我们常常发现某批量的key到时间应当过期删除了,但实际发现内存并没有得到释放,这就涉及到redis过期策略问题,redis的过期策略有两种:定期删除以及惰性删除。
1、定期删除
(1)redis每隔100ms就会随机抽取一些设置了过期时间的key检测是否过期,如果过期了就删除掉。也就是说redis并不是每次都检查所有的有过期时间的key,那样会引发很大的性能问题,可能大部分的时间可能都会花在遍历过期key上。
(2)由于并不是实时删除所有过期key,这就会导致存在明明某批量的key已经过了到期时间,但发现内存并没有得到释放的问题。
2、惰性删除
由于定期删除都是随机抽取有过期时间的key检查,就会存在很多过期了但并没有得到删除的key,所以引入了惰性删除的方式,也就是在查询某个key的时候再检查一下key是否已过期,如果已经过期,就删除掉,没有过期才返回给客户端。
二、内存淘汰机制
如果定期删除依然存在大量过期key且没有查询操作引发删除,内存的占用就会越来越高,当占用到一定程度后,就会通过redis的内存淘汰机制去删除掉。
1、内存淘汰策略
(1)内存淘汰机制有以下六种策略(可通过redis.conf进行配置):
# volatile-lru -> 使用类似LRU算法从设置了过期时间的key集合中移除一个key,用的较少
# allkeys-lru -> 使用类似LRU算法移除任意的key,比较常用
# volatile-lfu -> 使用类似LFU算法从设置了过期时间的key集合中移除一个key,用的较少
# allkeys-lfu -> 使用类似LFU算法移除任意的key,比较常用
# volatile-random -> 从设置了过期时间的key集合中随机删除某个key,很少用
# allkeys-random -> 随机删除某个key,很少用
# volatile-ttl -> 从设置了过期时间的key集合中删除最早过期的key,很少用
# noeviction -> 不移出任何key,直接报一个error给客户端,很少用
(2)默认情况的内存淘汰机制是noeviction,可通过以下配置调整
maxmemory-policy noeviction
2、redis的LRU/LFU
LRU:最近最少被使用( Least Recently Used)
LFU:最少被使用(Least Frequently Used)
redis的LRU/LFU都是采用近似随机算法进行实现,也就是随机获取一定量的key,然后移除掉最近最少被使用的key,可以通过以下配置采样数调整速度和精度,每次获取10个key比较接近真正的LRU,但需要花费更多的cpu,3的速度比较快,但不是很准确
maxmemory-samples 5