Redis过期Key删除策略:惰性删除与定期删除的配合机制
Redis服务器之所以能保持高性能,关键在于它不会在Key过期的瞬间立即执行删除操作,而是采用了一套精密的“惰性删除”与“定期删除”配合机制。这套机制完美平衡了CPU计算资源与内存空间资源。
一、 理解“惰性删除”机制
惰性删除是Redis最基础的清理策略。它的核心逻辑非常简单:只有当你试图访问一个Key时,Redis才会检查它是否过期。
- 执行 任意读或写命令访问某个Key(例如
GET或SET)。 - 调用
expireIfNeeded函数 检查 该Key是否设置了过期时间。 - 判断 当前系统时间是否已超过Key的过期时间戳。
- 执行 以下操作之一:
- 若未过期:保留 该Key,并 继续执行 后续命令。
- 若已过期:删除 该Key,并 返回 空值(nil)或执行特定逻辑。
这种策略极大地节省了CPU资源,因为Redis不需要时刻监控每一个Key。但如果大量过期Key长期不被访问,它们会一直占用内存,甚至导致内存泄漏。
二、 掌握“定期删除”机制
为了解决惰性删除带来的内存泄漏问题,Redis引入了定期删除策略。这可以看作是一个后台自动清理程序,通过“抽样”来清理过期Key。
定期删除的执行逻辑由 activeExpireCycle 函数实现,具体步骤如下:
- 启动 定时任务。Redis每秒执行约
10次该任务(可通过配置调整)。 - 随机 从设置了过期时间的字典中抽取一定数量的Key(默认为
20个)。 - 遍历 这些Key,删除 其中所有已过期的Key。
- 计算 抽样中过期Key的比例。
- 判断 该比例是否超过
25%。- 若超过:立即重复 步骤2,继续抽样清理。
- 若未超过:结束 本次循环,等待下一次定时任务触发。
以下流程图展示了定期删除的循环判断逻辑:
flowchart TD
A["Start: Timer triggers"] --> B["Extract random keys (default 20)"]
B --> C["Check expiration status"]
C --> D["Delete expired keys"]
D --> E{"Expired ratio >= 25%?"}
E -- "Yes" --> B
E -- "No" --> F["End: Wait for next cycle"]
这种策略限制了每次清理的CPU耗时,确保Redis不会因为清理任务而阻塞正常的请求处理。
三、 两者的配合策略
Redis在实际运行中,并非单独使用某一种策略,而是将惰性删除与定期删除紧密结合。
| 特性 | 惰性删除 | 定期删除 |
|---|---|---|
| 触发条件 | 访问 Key时被动触发 | 定时任务 主动 触发 |
| 资源消耗 | 极低,仅在读写时消耗CPU | 周期性消耗少量CPU |
| 内存清理效果 | 取决于访问频率,可能遗留大量垃圾 | 能够清理大部分过期Key |
| 适用场景 | 保证数据读取的一致性 | 作为补充,防止内存溢出 |
配合运作流程如下:
- 当客户端 发起请求 访问Key时,Redis 优先执行 惰性删除,确保客户端不会读取到已过期的脏数据。
- 在请求空闲期,定期删除任务 后台运行,主动清理那些尚未被访问到的过期Key,释放内存空间。
四、 调整配置参数
你可以通过修改 redis.conf 配置文件来优化定期删除的执行频率。
-
打开
redis.conf文件。 -
定位 到
hz参数配置项。hz 10 -
修改 数值以调整定时任务频率。
- 默认值为
10,表示每秒执行10次定期删除。 - 若 提高 该值(例如设为
100),Redis将更积极地清理过期Key,降低内存压力,但会增加CPU消耗。 - 若 降低 该值,可减少CPU使用率,但可能导致过期Key堆积。
- 默认值为
-
保存 配置文件并 重启 Redis服务使配置生效。

暂无评论,快来抢沙发吧!