Redis 的数据过期删除策略结合了 惰性删除(被动删除) 和 定期删除(主动删除) 两种机制,确保在内存占用和性能之间取得平衡。以下是详细说明:
1. 惰性删除(Lazy Expiration)
- 原理:在客户端访问某个键时,Redis 会先检查该键是否已过期。如果过期,则立即删除该键,并返回空值;如果未过期,则正常返回数据。
- 优点:
- 对 CPU 友好,仅在访问时触发检查,避免不必要的资源消耗。
- 缺点:
- 若大量过期键长期未被访问,会导致内存浪费(内存泄漏风险)。
2. 定期删除(Periodic Expiration)
- 原理:Redis 周期性(默认每秒 10 次,可通过
hz
配置调整)随机抽取部分设置了过期时间的键,检查并删除其中已过期的键。具体流程如下:- 随机选择数据库:每次从多个数据库中随机选择一个。
- 随机采样键:从该数据库的过期字典中随机选取
20
个键(可通过ACTIVE_EXPIRE_CYCLE_LOOKUPS_PER_LOOP
调整)。 - 删除过期键:删除这 20 个键中已过期的键。
- 自适应调整:若发现过期的键比例超过
25%
,则重复上述步骤继续检查,否则结束本轮检查。
- 优点:
- 减少内存浪费,通过周期性清理降低未访问过期键的堆积。
- 缺点:
- 需要合理配置频率和采样数量,避免过度占用 CPU。
3. 内存淘汰策略(补充机制)
当 Redis 内存不足时(即使定期和惰性删除未及时清理),会触发 内存淘汰机制(通过 maxmemory-policy
配置),常见的策略包括:
volatile-lru
:从已设置过期时间的键中淘汰最近最少使用的(LRU)。volatile-ttl
:淘汰剩余存活时间最短的键(TTL)。volatile-random
:随机淘汰设置了过期时间的键。allkeys-lru
/allkeys-random
:从所有键中淘汰(无论是否过期)。
4. 过期键的存储结构
- Redis 使用 过期字典(expires dict) 存储键的过期时间。每个键的过期时间戳记录在此字典中,惰性删除和定期删除均通过查询该字典判断键是否过期。
5. 总结与优化建议
- 策略结合:惰性删除 + 定期删除共同作用,覆盖主动和被动场景。
- 监控与调优:
- 监控
expired_keys
指标(通过info stats
)观察过期键删除情况。 - 调整
hz
参数提高定期删除频率(默认 10,范围 1~500),需权衡 CPU 开销。 - 设置合理的内存淘汰策略(如
volatile-lru
)防止内存溢出。
- 监控
- 极端场景:若过期键堆积严重,可考虑手动扫描清理(如通过
SCAN
命令)。
通过合理配置,Redis 能够在高效利用内存的同时保持高性能,适应不同业务场景需求。