文章目录
Redis的数据已经设置了TTL,不是过期就已经删除了吗?为什么还存在所谓的淘汰策略呢?这个原因我们需要从redis的过期策略聊起。
一、过期策略
1.定期删除
redis 会将每个设置了过期时间的 key 放入到一个独立的字典中,以后会定期遍历这个字典来删除到期的 key。
Redis 默认会每秒进行十次过期扫描(100ms一次),过期扫描不会遍历过期字典中所有的 key,而是采用了一种简单的贪心策略。
-
从过期字典中随机 20 个 key;
-
删除这 20 个 key 中已经过期的 key;
-
如果过期的 key 比率超过 1/4,那就重复步骤 1;
redis默认是每隔 100ms就随机抽取一些设置了过期时间的key,检查其是否过期,如果过期就删除。注意这里是随机抽取的。为什么要随机呢?你想一想假如 redis 存了几十万个 key ,每隔100ms就遍历所有的设置过期时间的 key 的话,就会给 CPU 带来很大的负载。
2.惰性删除
所谓惰性策略就是在客户端访问这个key的时候,redis对key的过期时间进行检查,如果过期了就立即删除,不会给你返回任何东西。
定期删除可能会导致很多过期key到了时间并没有被删除掉。所以就有了惰性删除。假如你的过期 key,靠定期删除没有被删除掉,还停留在内存里,除非你的系统去查一下那个 key,才会被redis给删除掉。这就是所谓的惰性删除,即当你主动去查过期的key时,如果发现key过期了,就立即进行删除,不返回任何东西.
总结:定期删除是集中处理,惰性删除是零散处理。
二、为什么需要淘汰策略
有了以上过期策略的说明后,就很容易理解为什么需要淘汰策略了,因为不管是定期采样删除还是惰性删除都不是一种完全精准的删除,就还是会存在key没有被删除掉的场景,所以就需要内存淘汰策略进行补充。
在使用Redis的过程中,当Redis缓存被写满之后,Redis就会根据配置的淘汰策略进行数据淘汰。从Redis4.0之后一共有8种淘汰策略。我们来分别看一下。
三、内存淘汰策略
1. noeviction
不进行数据淘汰,也是Redis的默认配置。这时,当缓存被写满时,再有写请求进来,Redis不再提供服务,直接返回错误。
2.volatile-random
缓存满了之后,在设置了过期时间的键值对中进行随机删除。
3.volatile-ttl
缓存满了之后,会针对设置了过期时间的键值对中,根据过期时间的先后顺序进行删除,越早过期的越先被删除。
4.volatile-lru
缓存满了之后,针对设置了过期时间的键值对,采用LRU算法进行淘汰,不熟悉LRU的可以看这篇文章。
5.volatile-lfu
缓存满了之后,针对设置了过期时间的键值对,采用LFU的算法进行淘汰。
6.allkeys-random
缓存满了之后,从所有键值对中随机选择并删除数据。
7.allkeys-lru
缓存写满之后,使用LRU算法在所有的数据中进行筛选删除。
8.allkeys-lfu
缓存满了之后,使用LRU算法在所有的数据中进行筛选删除。
在日常使用过程中,主要根据你的数据要求来配置相应的策略,这里我给你三点建议。
- 我们优先使用allkeys-lru 策略。这样,我们就可以借助LRU算法去淘汰那些不常用的数据,把最近最常用的放在缓存中,从而提高应用的性能。如果你的数据有明显的冷热区分,建议你使用allkeys-lru策略。
- 如果你的数据的访问频率相差不大,也没有冷热之分,直接使用allkeys-random 策略,随机选择淘汰的数据就行。
- 如果你的数据有置顶要求,比如置顶新闻等。那么我们就选择volatile-lru策略,同时不给置顶数据设置过期时间,这样一来,置顶的数据永远不会被删除,而其他设置了过期时间的数据,会更加LRU算法进行淘汰。