惰性删除、定期删除和内存淘汰是redis中三种独立的过期键处理机制:惰性删除仅在访问时检查并同步删除带ttl的键;定期删除每秒随机抽查带ttl键清理过期者,缓解惰性删除压力;内存淘汰则在内存超限时强制驱逐键腾空间,不区分是否过期。

惰性删除不等于内存淘汰,两者作用阶段完全不同
惰性删除只处理设置了 TTL 的键,且仅在访问时触发检查与同步删除;而内存淘汰(如 allkeys-lru)是在 used_memory 超过 maxmemory 后,强制驱逐键来腾出空间。它们不是同一层机制,也不会互相替代或覆盖。
过期键堆积会绕过惰性删除,直接触发内存淘汰
如果大量带 TTL 的键长期未被访问,惰性删除完全不生效,这些键会持续占用内存。一旦 used_memory 触达 maxmemory,Redis 就必须启动淘汰流程——哪怕其中 90% 的键其实已经过期。
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
- 此时淘汰策略可能选中一个「未过期但冷数据」的键,而不是那个「已过期却没人碰」的键
-
volatile-ttl策略虽优先淘汰 TTL 更短的键,但前提是它还在键空间里;而惰性删除没触发前,过期键仍算“存在”,所以该策略能起效 - 但若过期键太多、定期删除又太弱(比如
hz设置过低),volatile-ttl实际效果会打折扣
定期删除是惰性删除的必要补位,否则内存淘汰压力剧增
Redis 默认每秒执行 10 次定期删除(由 hz 参数控制),每次随机抽查 20 个带 TTL 的键并清理过期者。这个动作不保证清完,但能显著降低惰性删除的兜底压力。
-
hz值调太高(如 100)会增加 CPU 开销,尤其在键量极大时可能引发主线程抖动 -
hz值太低(如 1)会导致过期键积压,内存水位缓慢爬升,最终更频繁触发内存淘汰 - 生产环境建议保持默认
hz 10,若观察到expired_keys监控指标持续上升,再小幅上调至 20 并观察 CPU 使用率
大 key 删除场景下,惰性删除(unlink)和内存淘汰可能产生竞争
当一个超大 Hash 键(比如含 50 万字段)设置 TTL 后过期,惰性删除会在第一次 GET 时触发同步释放——这会造成明显延迟。而如果你用 unlink 主动删它,后台线程异步清理,主线程立刻返回,但此时内存还没真正释放。
- 如果在
unlink后、后台线程完成前,used_memory就已触达maxmemory,淘汰机制仍可能被触发 - 也就是说:
unlink解决的是「阻塞」问题,不是「内存即时回收」问题 - 真正释放内存的时间点取决于后台线程进度,可通过
info memory中的lazyfree_pending_objects实时观察
TTL 就万事大吉,其实没访问过的过期键,既不会被惰性删除,也不一定被定期删除扫到,最后全堆在内存里等淘汰机制来擦屁股。










