目录
[一、Redis 过期键的存储原理](#一、Redis 过期键的存储原理)
[【1】惰性删除(Lazy Expiration):"用的时候再检查"](#【1】惰性删除(Lazy Expiration):“用的时候再检查”)
[【2】 定期删除(Periodic Expiration):"定时批量清扫"](#【2】 定期删除(Periodic Expiration):“定时批量清扫”)
[【2】如何避免 "缓存雪崩"?](#【2】如何避免 “缓存雪崩”?)
在 Redis 开发中,缓存过期是保障内存高效利用的核心机制。如果不了解 Redis 如何处理过期键,可能会导致内存泄漏、缓存雪崩等严重问题。本文将从过期键的存储结构出发,详解三种核心过期策略,再到内存淘汰机制的联动逻辑,帮你彻底掌握 Redis 过期管理的底层逻辑。
一、Redis 过期键的存储原理
Redis 并不会为过期键单独开辟存储空间,而是通过 "键 - 值对"+"过期时间字典" 的组合方式管理:
- 核心字典(db->dict):存储正常的键值对(key-value);
- 过期字典(db->expires):存储键的过期时间(key->timestamp),其中 timestamp 是 Unix 时间戳(毫秒级)。
当我们执行 SET key value EX 30 命令时,Redis 会同时在两个字典中写入数据,确保查询键是否过期时,只需快速访问过期字典即可。
二、基于过期时间的删除策略
【1】惰性删除(Lazy Expiration):"用的时候再检查"
- 原理:只有当用户访问某个键(如 GET、HGET)时,Redis 才会检查该键是否过期。若过期则删除键,并返回空值;若未过期则正常返回数据。
- 优点:完全不消耗 CPU 资源在 "无用检查" 上,只在必要时执行删除操作,对 CPU 友好。
- 缺点:可能导致大量过期键堆积在内存中,造成 "内存泄漏"。例如,一个设置了 1 小时过期的键,若 1 小时后始终无人访问,它会一直占用内存。
【2】 定期删除(Periodic Expiration):"定时批量清扫"
为解决惰性删除的内存问题,Redis 增加了定期删除机制:
- 原理:Redis 每隔一段时间(默认 100ms,可通过 hz 配置调整)会执行一次 "过期键扫描",流程如下:
- 从过期字典中随机抽取 N 个键(N 可配置,默认 3 个);
- 检查这些键是否过期,删除已过期的键;
- 若删除的键占比超过 25%,则重复步骤 1,否则结束本次扫描。
- 优点:避免大量过期键堆积,同时通过 "随机抽样" 和 "占比阈值" 控制 CPU 消耗,防止扫描阻塞主线程。
- 注意点:hz 配置默认值为 10(即每秒扫描 10 次),过高会增加 CPU 负担,过低则可能导致过期键清理不及时。
三、基于内存淘汰的删除策略**(逐出算法)**
当 Redis 内存达到 maxmemory 限制时,即使有定期删除和惰性删除,仍可能存在未清理的过期键或永久键。此时 Redis 会触发 内存淘汰机制(Maxmemory Policy),根据预设策略删除部分键以释放内存。
【1】删除策略
检测易失数据(可能会过期的数据集server.db[i].expires)
① volatile-lru:挑选最近最少使用的数据淘汰
② volatile-lfu:挑选最近使用次数最少的数据淘汰
③ volatile-ttl:挑选将要过期的数据淘汰
④ volatile-random:任意选择数据淘汰
检测全库数据(所有数据集server.db[i].dict)
⑤ allkeys-lru:挑选最近最少使用的数据淘汰
⑥ allkeys-lfu:挑选最近使用次数最少的数据淘汰
⑦ allkeys-random:任意选择数据淘汰
放弃数据驱逐
⑧ no-enviction(驱逐):禁止驱逐数据(redis4.0中默认策略),会引发错误OOM(Out Of
Memory)达到最大内存后的,对被挑选出来的数据进行删除的策略
【2】生产环境推荐配置
- 若缓存中既有永久键(如基础配置)也有临时键(如用户会话),推荐 volatile-lru;
- 若缓存中所有键都是临时键(如纯缓存场景),推荐 allkeys-lru。
配置方式(redis.conf):
maxmemory 1024mb # 设置Redis最大内存(根据服务器配置调整) maxmemory-policy volatile-lru # 设置内存淘汰策略
四、常见问题与解决方案
【1】为什么设置了过期时间的键,到期后仍未被删除?
可能原因:
- 键未被访问(惰性删除未触发);
- 定期删除未扫描到该键(随机抽样机制导致);
- 内存未达 maxmemory,内存淘汰机制未触发。
解决方案:
- 避免设置过大的 hz 值,可适当调至 15-20(平衡 CPU 和清理效率);
- 对核心临时键,可主动执行 DEL 命令删除,而非依赖自动过期。
【2】如何避免 "缓存雪崩"?
缓存雪崩是指大量键同时过期,导致请求直接穿透到数据库。解决思路与过期策略相关:
- 给键的过期时间增加 "随机偏移量",例如 EX 300 + rand(0, 60),避免集中过期;
- 结合 volatile-lru 策略,确保即使部分键过期,仍有 LRU 淘汰机制保障内存可用。
五、总结
Redis 过期策略是 "惰性删除 + 定期删除" 的协同,再以 "内存淘汰机制" 为兜底,三者共同实现了 "低 CPU 消耗" 和 "低内存占用" 的平衡。在实际开发中,需注意:
- 合理配置 maxmemory 和 maxmemory-policy,避免内存溢出;
- 对核心临时键,主动管理过期时间,减少对自动策略的依赖;
- 避免设置过大的 hz 值,防止 CPU 过载。
掌握这些底层逻辑,才能在高并发场景下,让 Redis 缓存既高效又稳定。
感谢你花时间读到这里~ 如果你觉得这篇内容对你有帮助,不妨点个赞让更多人看到;如果有任何想法、疑问,或者想分享你的相关经历,欢迎在评论区留言交流,你的每一条互动对我来说都很珍贵~ 我们下次再见啦!😊😊