前言
redis键值对过期后通过命令虽然无法取出数据,并不代表被物理删除了,只是对外不可见。此时可以简单理解为被逻辑删除,那么这些被逻辑删除的键值对何时被物理删除呢,这正是删除策略所决定的。当redis内存被写满,会触发redis内存的淘汰策略。
一、概念
删除策略:设置了过期时间的键值对什么时候真正从redis内存中物理删除;
淘汰策略:redis内存被写满,以什么样的方式淘汰键值对;
简言之,前者强调什么时间删除数据、后者强调哪些数据被淘汰。
二、删除策略
1.定期删除
redis 会将每个设置了过期时间的 key 放入到一个独立的字典中,以后会定期遍历这个字典来删除到期的 key。redis 默认会每秒进行十次过期扫描,过期扫描不会遍历过期字典中所有的 key,而是采用了一种简单的贪心策略:
1).从过期字典中随机 20 个 key;
2).删除这 20 个 key 中已经过期的 key;
3).如果过期的 key 比率超过 1/4,那就重复步骤 1);
redis默认是每隔 100ms就随机抽取一些设置了过期时间的key,检查其是否过期,如果过期就删除。注意这里是随机抽取的。为什么要随机呢?你想一想假如 redis 存了几十万个 key ,每隔100ms就遍历所有的设置过期时间的 key 的话,就会给 CPU 带来很大的负载。
2.惰性删除
定期删除可能会导致很多过期key到了时间并没有被删除掉。所以就有了惰性删除。所谓惰性删除就是在客户端访问这个key的时候,redis对key的过期时间进行检查,如果过期了就立即删除。
总结:定期删除是集中处理,惰性删除是零散处理。redis默认采用采用定期删除+惰性删除结合的方式。
三、淘汰策略
redis目前共提供了8种内存淘汰策略,其中有两种基于LFU算法的策略是redis4.0版本之后增加的。
noeviction:只返回错误,不会删除任何key。该策略是Redis的默认淘汰策略,一般不会选用
volatile-ttl:将设置了过期时间的key中即将过期(剩余存活时间最短)的key删除掉
volatile-random:在设置了过期时间的key中,随机删除某个key
allkeys-random:从所有key中随机删除某个key
volatile-lru:基于LRU算法,从设置了过期时间的key中,删除掉最近最少使用的key
allkeys-lru:基于LRU算法,从所有key中,删除掉最近最少使用的key。该策略是最常使用的策略
redis4.0以后增加的策略
volatile-lfu:基于LFU算法,从设置了过期时间的key中,删除掉最不经常使用(使用次数最少)的key
allkeys-lfu:基于LFU算法,从所有key中,删除掉最不经常使用(使用次数最少)的key
如果不了解LRU(即最近最少使用)、LFU(最近最不经常使用)算法,请参考文档
一文带你读懂LFU算法
一文带你读懂LRU算法