Redis 过期删除策略与内存淘汰策略有何区别?如何配置?
结论先行:两者处理对象完全不同——过期删除策略解决"已过期 key 何时被清理"的问题,采用惰性删除 + 定期删除的组合;内存淘汰策略解决"内存写满时如何腾空间"的问题,由 maxmemory-policy 决定驱逐哪些存活 key。回答时先点破这个区别,再分别展开。
一、过期删除策略
- 惰性删除:每次访问 key 时检查是否过期,过期则删除,省 CPU 但过期 key 可能长时间残留占内存;
- 定期删除:serverCron 周期性随机抽取一批带过期时间的 key 检查删除,兼顾 CPU 与内存,但不是全量扫描;
- 两者组合:惰性删除兜底 + 定期删除主动清理,Redis 不采用定时器逐 key 删除,避免大量定时器开销;
- 主从一致性:过期 key 由主库删除后向从库发送 DEL,从库不主动删除,避免主从数据不一致;
- 定期删除的执行节奏:由 serverCron 驱动,每轮抽样数量与单轮耗时都有上限,防止长时间占用主线程;
- 过渡状态理解:过期 key 大量堆积时,读写路径与定期删除会共同触发清理,存在逻辑过期但物理暂未回收的窗口。
二、内存淘汰策略
| 策略 | 含义 | 备注 |
|---|---|---|
| noeviction | 写满后直接报错 | 默认策略 |
| allkeys-lru | 全 key 淘汰最久未使用 | 常用 |
| volatile-lru | 仅从设了过期时间的 key 中淘汰 | 无过期 key 时等同 noeviction |
| allkeys-lfu / volatile-lfu | 淘汰访问频率最低的 key | Redis 4.0+ |
| allkeys-random / volatile-random | 随机淘汰 | 兜底策略 |
| volatile-ttl | 优先淘汰剩余 TTL 最短的 key | 仅限带过期时间的 key |
三、配置与命令
# 设置内存上限与淘汰策略
CONFIG SET maxmemory 4gb
CONFIG SET maxmemory-policy allkeys-lfu
# 查看 key 的剩余存活时间
redis-cli TTL mykey # -1 表示未设过期时间,-2 表示 key 不存在
redis-cli CONFIG GET maxmemory # 查看当前内存上限配置
常见追问 / 记忆点
- 追问:淘汰发生在主库还是从库?答:主要在内存写满的节点触发,生产上主从内存配置应一致,避免主从淘汰不一致。
- 追问:LFU 和 LRU 有何区别?答:LRU 只看最近访问时间,LFU 统计访问频次并带衰减机制,能防热点扫描型污染。
- 追问:为什么推荐 allkeys 而不是 volatile?答:volatile 系依赖业务正确设置过期时间,漏设过期时间的 key 永远不会被淘汰。
- 记忆点:过期删除是"清尸体",内存淘汰是"赶活人",先分清对象再答策略名,不易丢分。