Redis 内存淘汰机制(8种策略+LRU/LFU底层原理)
Redis 是内存数据库,最大内存用完后必须淘汰数据,否则无法写入新数据、直接 OOM。内存淘汰机制就是 Redis 内存满了之后「删谁、怎么删」的核心规则。
本文覆盖:maxmemory 机制、8种淘汰策略、LRU 近似实现原理、LFU 热点淘汰原理、LRU/LFU 对比、生产选型、面试高频问法。
一、前置基础:maxmemory 触发条件
1. 最大内存配置
redis.conf 核心参数:
- maxmemory 10gb:设置 Redis 最大可用内存
- maxmemory-policy:内存满后的淘汰策略
默认行为:不配置 maxmemory 时,64位Redis 不限制内存,会一直吃满机器内存,导致机器卡死、OOM。
2. 什么时候触发淘汰?
每次执行 写命令(set、hset、incr、lpush 等)时:
判断内存是否超出 maxmemory → 超出则执行对应淘汰策略,腾出空间后再写入新数据。
二、Redis 八种内存淘汰策略(面试必背)
分为三大类:不淘汰、淘汰TTL、淘汰冷热
1. 禁止淘汰(默认策略)
- noeviction:内存满后不删除任何数据,直接报错 OOM。
适用场景:纯持久化、不允许丢数据的核心业务,生产基本不用。
2. 只淘汰带过期时间的 key(TTL 策略)
- volatile-ttl:在带过期的key中,优先删除 剩余过期时间最短 的(快到期先删)
- volatile-lru:带过期key中,删除 最久未使用
- volatile-lfu:带过期key中,删除 访问频次最低
- volatile-random:带过期key中,随机删除
特点:永久key绝对不删,只动有过期时间的缓存key。
3. 全局淘汰(所有key,无论是否过期)
- allkeys-lru:全局所有key,删除最久未使用(生产最常用)
- allkeys-lfu:全局所有key,删除访问频次最低(Redis4.0+ 最优)
- allkeys-random:全局随机删除,极度不推荐
三、核心重点:Redis LRU 底层原理(面试深坑)
重要结论:Redis 并不是严格 LRU,是「近似 LRU」!
严格LRU需要维护链表、每次访问移动节点,消耗巨大CPU,Redis 为高性能做了轻量化优化。
1. LRU 核心数据结构
每个 Redis key 对象(redisObject)内部维护:
- lru 字段(24bit):记录该key 最后一次访问的时间戳
无需链表、无需排序,仅靠时间戳判断冷热。
2. 近似 LRU 淘汰流程
内存满需要淘汰时:
- 随机采样 5个key(默认参数 maxmemory-samples)
- 对比这5个key的 lru 时间戳
- 删除其中 最久没访问 的key
- 循环往复,直到内存够用
优点:极高性能、几乎无CPU开销
缺点:不是绝对精准,极个别冷门key可能侥幸存活,但误差极小,工程完全可用
3. 采样参数说明
maxmemory-samples 5
采样值越大越精准、越耗CPU;5是性能与精度的最佳平衡点。
四、Redis LFU 底层原理(Redis4.0+ 最强淘汰)
LFU:最少频次使用淘汰,解决 LRU 的致命缺陷:LRU只看时间、不看热度。
1. LRU 的缺陷
举例:一个高频热点key刚刚10秒没人访问,一个冷门key刚刚被访问一次。
LRU 会误删热点key、保留垃圾冷门key,冷热判断失真。
2. LFU 字段结构(24bit)
redisObject 的 lru 字段复用拆分:
- 低 16bit:访问计数器 counter:记录访问频次
- 高 8bit:递减时间戳:记录上一次衰减时间
3. LFU 核心机制(智能衰减)
LFU 不是简单累加计数,否则老key永远删不掉,核心是热度衰减:
- key 长期不访问,计数器自动衰减变小
- 新访问 key 计数上涨快
- 真正实现:淘汰长期冷门,保留持续热点
4. LFU 淘汰流程
- 随机采样若干key
- 对比访问频次 counter
- 删除频次最低的key
- 频次相同再比较访问时间
五、LRU vs LFU 终极对比(面试高频)
| 维度 | LRU | LFU |
|---|---|---|
| 判断依据 | 最近访问时间 | 历史访问热度+时间衰减 |
| 冷热识别 | 弱,容易误删热点 | 极强,精准识别真实热点 |
| 新老key公平性 | 新key优势大 | 自动衰减,公平合理 |
| 版本支持 | 全版本 | 4.0+ |
| 生产推荐 | 通用场景 | 高并发热点场景最优 |
六、生产环境最佳策略选型(面试标准答案)
- 通用业务、绝大多数缓存场景:
allkeys-lru
兼顾冷热淘汰、稳定、无副作用、运维友好 - 高并发热点业务(商品、榜单、首页):
allkeys-lfu
精准保留热点,淘汰僵尸冷数据,缓存命中率最高 - 希望永久key不被删除、只删过期缓存:
volatile-lru - 不允许丢数据、纯存储业务:
noeviction,配合严格内存监控
七、面试高频八股总结(直接背诵)
- Redis内存满了怎么办? 触发内存淘汰策略,采样删除冷热key,腾出空间再写入。
- Redis LRU 是真LRU吗? 不是严格LRU,是采样式近似LRU,靠对象24bit时间戳+随机采样淘汰,性能极高。
- LRU缺点? 只看访问时间,不看访问频次,会误删短期未访问的热点key。
- LFU优势? 基于访问热度+自动衰减,精准区分冷热数据,缓存命中率更高。
- 为什么不用严格LRU? 需要维护链表排序,CPU开销巨大,Redis追求极致性能。