过期删除
# redis怎么进行过期删除?
我们set key的时候,都可以给一个expire time,就是过期时间,通过过期时间可以指定这个key存活的时间。
如果假设你设置了一批key只能存活1个小时,那么接下来1小时后,redis是怎么对这批key进行删除的?
定期删除+惰性删除。
# 1 定期删除
redis默认是每隔 100ms 就随机抽取一些设置了过期时间的key,检查其是否过期,如果过期就删除。注意这里是随机抽取的。为什么要随机呢?你想一想假如 redis 存了几十万个 key ,每隔100ms就遍历所 有的设置过期时间的 key 的话,就会给 CPU 带来很大的负载!
# 2 惰性删除
定期删除可能会导致很多过期 key 到了时间并没有被删除掉。所以就有了惰性删除。假如你的过期 key,靠定期删除没有被删除掉,还停留在内存里,除非你的系统去查一下那个 key,才会被redis给删除掉。这就是所谓的惰性删除,也是够懒的哈!
但是仅仅通过设置过期时间还是有问题的。我们想一下:如果定期删除漏掉了很多过期 key,然后你也没及时去查, 也就没走惰性删除,此时会怎么样?如果大量过期key堆积在内存里,导致redis内存块耗尽了。怎么解决这个问题呢? -- redis内存淘汰机制。
# 3 主动清理策略
提示
当前已用内存超过maxmemory限定时,触发主动清理策略。
根据自身业务类型,配置好maxmemory-policy(默认是noeviction),
推荐使用volatile-lru。
主动清理策略在Redis4.0之前一共实现了6种内存淘汰策略,在4.0之后,又增加了2种策略,总共8种策略:
# a) 设置过期时间的key做处理
# 3.1 volatile-ttl
在筛选时,会针对设置了过期时间的键值对,根据过期时间的先后进行删除,越早过期的越先被删除。
# 3.2 volatile-random
就像它的名称一样,在设置了过期时间的键值对中,进行随机删除。
# 3.3 volatile-lru
会使用 LRU 算法筛选设置了过期时间的键值对删除。
# 3.4 volatile-lfu
会使用 LFU 算法筛选设置了过期时间的键值对删除。
# b) 针对所有的key做处理
# 3.5 allkeys-random
从所有键值对中随机选择并删除数据。
# 3.6 allkeys-lru
使用 LRU 算法在所有数据中进行筛选删除。
# 3.7 allkeys-lfu
使用 LFU 算法在所有数据中进行筛选删除。
# c) 不处理
# 3.8 noeviction
不会剔除任何数据,拒绝所有写入操作并返回客户端错误信息"(error) OOM command not allowed when used memory",此时Redis只响应读操作。
# 4 LFU、LRU数据淘汰策略
# 4.1 LRU
LRU 算法(Least Recently Used,最近最少使用)
淘汰很久没被访问过的数据,以最近一次访问时间作为参考。
# 4.2 LFU
LFU 算法(Least Frequently Used,最不经常使用)
淘汰最近一段时间被访问次数最少的数据,以次数作为参考。
# 4.3 配置建议
当存在热点数据时,LRU的效率很好,但偶发性的、周期性的批量操作会导致LRU命中率急剧下降,缓存污染情况比较严重。这时使用LFU可能更好点。