Redis 的 过期策略(Expiration Policy) 和 内存淘汰策略(Eviction Policy) 是两种不同但协同工作的机制,共同管理内存中的数据生命周期。以下是清晰对比和详细解析:
一、过期策略(Expiration Policy)
目的:自动删除设置了过期时间(TTL)的键,无需等待内存不足。
核心机制:
-
惰性删除(Lazy Expiration)
- 触发时机:当客户端访问一个键时,Redis 会检查该键是否过期。
- 行为:若过期则立即删除,并返回
nil
;否则正常返回数据。 - 优点:对 CPU 友好,只在访问时消耗资源。
- 缺点:若过期键长期不被访问,会占用内存(内存泄漏风险)。
-
定期删除(Periodic Expiration)
- 触发时机:Redis 周期性随机抽取部分过期键(默认每秒 10 次)。
- 行为:
- 采样检查
ACTIVE_EXPIRE_CYCLE_LOOKUPS_PER_LOOP
(默认 20)个键。 - 删除其中已过期的键,若过期键占比 >25%,则重复采样。
- 采样检查
- 优点:减少内存泄漏风险。
- 缺点:CPU 占用可能突增,需平衡频率(通过
hz
配置调整)。
注意:过期策略只处理显式设置 TTL 的键,不涉及未设置过期的键。
二、内存淘汰策略(Eviction Policy)
目的:当内存达到 maxmemory
限制时,主动删除键释放空间(无论是否过期)。
触发条件:used_memory > maxmemory
(需先配置 maxmemory
参数)。
8 种策略:
类型 | 策略 | 删除规则 | 适用场景 |
---|---|---|---|
不淘汰 | noeviction (默认) | 拒绝写入,返回 OOM 错误 | 数据绝对不可丢失 |
仅淘汰过期键 | volatile-ttl | 优先删除 TTL 最短的键 | 快速清理即将过期的数据 |
volatile-random | 随机删除过期键 | 过期键分布均匀 | |
volatile-lru | 删除最近最少使用的过期键(LRU 算法) | 缓存场景,关注近期访问 | |
volatile-lfu | 删除访问频率最低的过期键(LFU 算法) | 保留高频访问键(Redis 4.0+) | |
淘汰所有键 | allkeys-random | 随机删除任意键 | 数据无访问规律 |
allkeys-lru | 删除最近最少使用的键(全局 LRU) | 通用缓存场景(推荐) | |
allkeys-lfu | 删除访问频率最低的键(全局 LFU) | 保留全局热点数据(Redis 4.0+) |
三、两者协同工作流程
- 写入新数据
- 若内存不足 → 触发 内存淘汰策略 删除键 → 腾出空间后写入。
- 读取数据
- 若键存在但过期 → 惰性删除 触发 → 删除并返回
nil
。
- 若键存在但过期 → 惰性删除 触发 → 删除并返回
- 后台运行
- 定期删除 持续清理过期键,减少内存压力。
四、关键注意事项
- 过期键的删除优先级
- 内存淘汰时,
volatile-*
策略只从过期键中选择,即使未过期键占用更多内存。 allkeys-*
策略无视 TTL,可能删除未过期的常用键。
- 内存淘汰时,
- 内存淘汰策略必须配置
- 若未设置
maxmemory
,Redis 不会触发任何淘汰(直到 OOM 被系统杀死)。
- 若未设置
- LRU/LFU 是近似算法
- Redis 为节省内存,使用采样删除(非精确 LRU/LFU),可通过
maxmemory-samples
调整精度(默认 5,值越大越精确,CPU 越高)。
- Redis 为节省内存,使用采样删除(非精确 LRU/LFU),可通过
- 生产环境推荐
- 纯缓存:
allkeys-lru
或allkeys-lfu
- 持久化部分数据:
volatile-lru
+ 对关键数据不设置 TTL。
- 纯缓存:
总结:核心区别
特性 | 过期策略 | 内存淘汰策略 |
---|---|---|
目标 | 清理过期键 | 防止内存溢出(OOM) |
触发条件 | 键过期 + 访问/定期扫描 | 内存达到 maxmemory |
作用范围 | 仅带 TTL 的键 | 所有键或带 TTL 的键(依策略而定) |
主动性 | 被动(惰性) + 半主动(定期) | 主动删除 |
合理配置两者,是保障 Redis 高性能与稳定性的关键!