Redis 过期 Key 删除机制详解
1. 过期 Key 的三种删除策略
Redis 采用 惰性删除(Lazy Deletion) 、定期删除(Periodic Deletion) 和 内存淘汰机制(Eviction) 来管理过期 key。
(1)惰性删除(Lazy Deletion)
机制: 只有当客户端访问某个 key 时,Redis 才会检查它是否过期,如果已过期则删除。
优缺点:
- ✅ 低 CPU 开销,不会主动扫描 key。
- ❌ 过期但未被访问的 key 仍占用内存。
示例:
SET key1 "hello" EX 10 # 10秒后过期
- 如果 10 秒后访问
GET key1,Redis 发现已过期,则删除 key 并返回nil。 - 如果从不访问
key1,它仍然占用内存,直到 Redis 触发内存淘汰策略。
(2)定期删除(Periodic Deletion)
机制: Redis 默认每 100ms(10Hz) 触发一次扫描,随机抽样 部分带有过期时间的 key,并删除已过期的 key。
优缺点:
- ✅ 减少内存占用,避免无用 key 堆积。
- ❌ 不能保证所有过期 key 都会被立即删除。
示例:
SET key2 "world" EX 5 # 5秒后过期
- 5 秒后,即使没有
GET key2,Redis 可能会主动删除它(但不保证立即删除)。
(3)内存淘汰机制(Eviction)
机制: 当 Redis 触及最大内存限制(maxmemory)时,触发内存淘汰策略删除部分 key。
可选策略(maxmemory-policy 配置):
- volatile-lru:从 设置了 TTL 的 key 中,淘汰 最近最少使用(LRU) 的 key。
- allkeys-lru:所有 key(不论是否有 TTL)使用 LRU 淘汰。
- volatile-random:从 设置了 TTL 的 key 中,随机删除。
- allkeys-random:从 所有 key 中随机删除。
- volatile-ttl:删除最接近过期的 key。
- noeviction(默认):内存满时,不删除 key,只返回错误。
示例:
CONFIG SET maxmemory 100mb
CONFIG SET maxmemory-policy allkeys-lru
- 当 Redis 占满 100MB 内存时,删除最近最少使用(LRU)的 key,以释放空间。
2. 过期 Key 删除策略对比
| 策略 | 触发时机 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|---|
| 惰性删除 | 访问 key 时 | 低 CPU 消耗 | 可能占用多余内存 | 低访问量的数据 |
| 定期删除 | Redis 每 100ms 触发 | 控制 CPU 开销 | 可能有少量过期 key 残留 | 适用于大多数场景 |
| 内存淘汰 | 触及 maxmemory | 避免 OOM | 可能误删数据 | 高并发 + 大数据量场景 |
3. Redis 过期 Key 删除策略的优化
(1)合理设置 expire,减少遗留 key
- 避免给所有 key 设置
expire,防止 Redis 频繁扫描。 - 仅给Session、验证码、热点数据等需要自动过期的数据加 TTL。
SET user:123 "data" EX 3600 # 1小时后自动删除
(2)调整 hz 配置,优化定期删除频率
hz控制 Redis 后台任务的执行频率(包括过期 key 清理)。- 默认
hz=10(即每 100ms 触发一次)。 - 高负载场景可适当调高(如
hz=50),加快过期 key 的删除速度。
CONFIG SET hz 50
(3)选择合适的 maxmemory-policy,防止 OOM
- 如果是缓存场景(如 CDN、Session 缓存):
allkeys-lru。 - 如果有 TTL 机制(如消息队列):
volatile-ttl。 - 如果不允许丢数据:
noeviction(但可能导致 OOM)。
CONFIG SET maxmemory-policy allkeys-lru
4. 总结
-
Redis 过期 key 采用:惰性删除 + 定期删除 + 内存淘汰。
-
惰性删除:访问时才删除,占用低 CPU,但可能导致内存泄露。
-
定期删除:Redis 每 100ms 触发扫描部分 key,删除过期 key。
-
内存淘汰:内存超限时,触发淘汰策略(LRU、TTL 等)。
-
优化建议:
- 合理设置 TTL,减少遗留 key。
- 调整
hz参数,优化删除效率。 - 选对
maxmemory-policy,防止 OOM。
🚀 合理优化 Redis 的过期 key 机制,可以有效提升性能,减少内存占用,提高缓存命中率!