思维导图
数据过期删除策略的思维导图如下:

内存淘汰策略的思维导图如下:

一、数据过期策略

(一)什么是 Redis 的数据过期删除策略?
Redis 支持对数据设置有效时间,数据过期以后,Redis 就需要将数据从内存中删除。
比如: set name qingxue 10
那么 name - qingxue 的有效时间就是 10 秒
Redis 里的数据可以按照不同的规则进行删除,这种删除规则就被称之为数据过期删除策略。
数据过期删除策略 = 过期删除策略 = 数据过期策略 = 数据删除策略
(二)Redis 的数据删除策略有哪些?
1. 惰性删除
什么是惰性删除: 设置该 key 过期时间后,我们不去管它,当需要该 key 时,我们再检查其是否过期,如果过期,我们就删掉它,反之返回该 key。
比如:
go
set name zhangsan 10
get name // 发现 name 过期了,直接删除该 key
优点: 对 CPU 友好,只会在使用该 key 时才会进行过期检查,对于很多用不到的 key 不用浪费时间进行过期检查。
缺点: 对内存不友好,如果一个 key 已经过期,但是一直没有使用,那么该 key 就会一直存在内存中,内存永远不会释放。如果大量的 key 已经过期,都没人访问、也不会删除,就会造成内存浪费。
2. 定期删除
什么是定期删除: 每隔一段时间,我们就对 一些 key 进行检查,删除 Redis 里面过期的 key(从一定数量的数据库中取出一定数量的随机 key 进行检查,并删除其中的过期key)。
定期清理有两种模式:SLOW 模式 和 FAST 模式
- SLOW 模式是定时任务。
- 执行频率默认为10hz,10 hz = 每秒执行 10 次 = 每个执行固定耗时 100 ms
- 每次清理操作的耗时不能超过 25 ms,因为清理操作要尽量少得去影响主进程操作。
- hz 可以通过修改配置文件 redis.conf 的 hz 选项来调整这个次数
- FAST 模式执行频率不固定。
- 但是,两次清理操作的时间间隔不低于 2 ms;
- 每次清理操作的耗时不能超过1ms,这个时间更短,主要原因是尽量不要占用主进程的操作。
优点:
- 可以通过限制删除操作执行的时长和频率来减少删除操作对 CPU 的影响。
- 另外,定期删除也能有效释放过期键占用的内存。
缺点: 难以确定删除操作执行的时长和频率。
- 执行得太频繁,对 CPU 不友好
- 执行得太少,又和惰性删除一样,过期的数据不会得到及时释放。
(三)Redis 的过期删除策略
Redis 的过期删除策略:惰性删除 + 定期删除 两种策略进行配合使用。
二、内存淘汰策略

(一)什么是内存淘汰策略?
当 Redis 中的内存不够用时,此时再向 Redis 中添加新的 key,那么 Redis 就会按照某一种规则将内存中的数据删除掉,这种数据的删除规则被称之为内存淘汰策略,有时也被称为数据淘汰策略。
内存淘汰策略 = 数据淘汰策略
数据过期策略 ≠ 内存淘汰策略
数据过期策略,说的是:某些 key 设置了过期时间删除的问题
内存淘汰策略,说的是:Redis 内存不够,却依然要往 Redis 里面添加数据的时候,Redis 就会按照某种规则将内存中的数据删掉。
(二)数据的淘汰策略有哪些?
Redis 支持 8 种不同策略来选择要删除的key:
-
noeviction:不淘汰任何key,但是内存满时不允许写入新数据(默认策略)

-
volatile-ttl:对设置了 TTL 的 key,比较 key 的剩余 TTL 值,TTL 越小就越先被淘汰。
-
allkeys-random:对全体 key,随机进行淘汰。
-
volatile-random:对设置了 TTL 的 key,随机进行淘汰。
-
allkeys-lru:对全体key,基于 LRU 算法进行淘汰。
-
volatile-lru:对设置了 TTL 的key,基于 LRU 算法进行淘汰。
-
allkeys-lfu:对全体 key,基于 LFU 算法进行淘汰。
-
volatile-lfu:对设置了 TTL 的 key,基于 LFU 算法进行淘汰。
这 8 种 策略不用全记住,重点记 LRU 和 LFU,面试的时候要会描述出这两种算法。
1. LRU
LRU(Least Recently Used)最近最少使用。
用当前时间减去最后一次访问时间,这个值越大则淘汰优先级越高。
比如:key1 是在 3s 前访问的,key2 是在 9s 前访问的,根据 LRU 算法,Redis 会删除 key2.
2. LFU
LFU(Least Frequently Used)最少频率使用。
会统计每个key的访问频率,值越小淘汰优先级越高。
比如:key1 最近访问了 4次,key2 最近访问了 9 次,根据 LFU 算法,Redis 会删除 key1.
(三)如何选择数据淘汰策略?
1.优先使用 allkeys-lru 策略。
如果业务没有任何要求,我们建议优先使用 allkeys-lru 策略。
因为这样可以充分利用 LRU 算法的优势,把最近最常访问的数据留在缓存中。
为什么不选择 LFU?
在实际应用中,访问频率不一定能准确反映数据的热度,
比如某个数据在某个时间段内它被访问了很多次,但是在其他时间段内就很少被访问,那这种时候如果仅仅按照访问频率来判断数据的热度,就可能会出现误判。
2.如果业务中数据访问频率差别不大,也没有明显冷热数据区分,建议使用 alkeys-random,随机选择淘汰。
3.如果业务中有置顶的需求,可以使用 volatile-lru 策略,同时置顶数据不设置过期时间,这些数据就一直不被删除会淘汰其他设置过期时间的数据。
4.如果业务中有短时高频访问的数据,可以使用 allkeys-lfu 或 volatile-lfu 策略。
三、相关面试题
1. Redis 的数据过期删除策略有哪些?
在 Redis 中提供了两种数据过期删除策略。
第一种是惰性删除,就是说在设置一个 key 的过期时间后,我们就不去管它。
当需要使用该 key 时,我们再检查其是否过期:
- 如果过期,我们就删掉它;
- 如果没过期,我们就返回该 key。
第二种是定期删除,就是说每隔一段时间,我们就对一些 key 进行检查,删除里面过期的 key。
定期清理有两种模式:
- SLOW 模式是定时任务,执行频率默认为10hz,每次不超过25ms,可以通过修改配置文件 redis.conf 的 hz 选项来调整这个次数。
- FAST 模式执行频率不固定,每次事件循环会尝试执行,但两次间隔不低于 2ms,每次耗时不超过1ms。
**Redis 的过期删除策略:**惰性删除 + 定期删除** 两种策略进行配合使用。
2. 内存淘汰策略有哪些?
等价问题:数据淘汰策略有哪些?
Redis 中提供了 8 种内存淘汰策略。
默认是 noeviction,不删除任何数据,内部不足直接报错。
淘汰策略是可以在 Redis 的配置文件中进行设置的。
这里面有两个非常重要的概念,一个是 LRU,另外一个是 LFU。
- LRU 就是最近最少使用
- 用当前时间减去最后一次访问时间,这个值越大则淘汰优先级越高。
- LFU 就是最少频率使用
- 会统计每个 key 的访问频率,值越小就越先淘汰
平常开发种常用的是 allkeys-lru,挑选最近最少使用的数据淘汰,把一些经常访问的 key 留在 Redis 中。
3. 数据库有 1000 万数据,Redis 只能缓存 20w 数据,如何保证 Redis 中的数据都是热点数据?
我们可以使用 allkeys-lru 淘汰策略,挑选最近最少使用的数据进行淘汰。
这样内存中留下来的都是经常访问的热点数据
4. Redis 内存用完了会发生什么?
主要看内存淘汰策略是什么。
如果是默认的配置 noeviction,会直接报错。