← 返回首页
二、6 种内存淘汰策略(
Redis 怎么淘汰过期 key?
Redis 过期 Key 淘汰机制(分两套:过期删除 + 内存满时淘汰)
一、过期 Key 删除策略(针对设置了 TTL 的键)
Redis 处理过期 key 有三种策略同时配合,不存在单一方案。
1. 惰性删除(被动删除,访问时才删)
-
逻辑:只有当客户端读取 key 时,Redis 先检查是否过期,过期直接删除并返回
nil。 -
优点:不占用 CPU,平时无额外开销。
-
缺点:如果 key 长期不被访问,哪怕早已过期,会一直占用内存。
2. 定期主动删除(后台定时扫描)
Redis 后台每隔一段时间执行定时任务,随机抽取一批带过期的 key 检测清理:
-
每秒执行 10 次(
hz=10,可配置); -
每次随机抽取20 个带过期的 key;
-
删除其中所有已过期 key;
-
若本轮删除的过期 key 超过 25%,立刻重复本轮扫描,防止大量过期堆积。
-
优点:主动释放内存,弥补惰性删除缺陷。
-
缺点:不会全库遍历,冷门长期未访问的过期 key 仍可能残留。
3. 内存淘汰(maxmemory 触发,最关键兜底)
当内存达到
maxmemory 上限时,Redis 执行淘汰策略,这里会同时清理:-
优先删掉所有已过期的 key;
-
若清理完过期 key 内存仍不足,再根据配置策略删除未过期的正常 key。
二、6 种内存淘汰策略(maxmemory-policy)
maxmemory 10gb maxmemory-policy volatile-lru
分为两大类:只淘汰带过期的 key、淘汰全部 key
只针对设置了 TTL 的 key(volatile 系列)
-
volatile-lru(常用默认) 从有过期时间的 key 中,淘汰最近最少使用的。 -
volatile-lfu淘汰访问频率最低的 key(Redis4.0+)。 -
volatile-random随机删除带过期的 key。 -
volatile-ttl优先删除剩余存活时间最短的 key。
所有 key 都参与淘汰(allkeys 系列)
-
allkeys-lru全部 key 里删最少使用,适合缓存场景。 -
allkeys-lfu全部 key 删访问频率最低。
拒绝淘汰(生产极少用)
-
noeviction:内存满直接报错,不删任何 key,写入返回 OOM。
三、完整过期清理流程(时序)
-
写入 key 带
expire:存入过期字典(expires) 记录到期时间; -
日常:
-
客户端读 key → 惰性删除;
-
后台定时任务 → 随机批量清理过期;
-
-
内存达到 maxmemory: ① 先遍历清理所有过期 key; ② 内存仍超阈值,按
maxmemory-policy删正常 key; -
RDB/AOF 持久化:
-
RDB:持久化时忽略已过期 key;
-
AOF:key 过期删除时生成
DEL指令写入 AOF。
-
四、补充关键细节
-
过期精度:毫秒级,基于系统时间;修改服务器时间会导致过期判断错乱。
-
主从过期同步: 主库删除过期 key 后,会向从库发送
DEL命令;从库不会主动执行过期删除,只同步主库删除结果,避免主从不一致。 -
批量清理过期命令:
-
SCAN遍历过滤过期; -
UNLINK异步删除大 key,不阻塞主线程; -
EXPIRE/PEXPIRE设置过期。
-
-
优化建议:
-
缓存场景推荐
allkeys-lru; -
部分持久数据 + 缓存混合用
volatile-lru; -
大 key 尽量用
UNLINK替代DEL; -
合理设置
maxmemory,不要等系统 OOM。
-
极简总结
日常靠「惰性删除 + 定期扫描」清过期;内存撑爆时先清全部过期,不够再按 LRU/LFU 等策略删正常 key。