volatile-ttl 不会精准淘汰“马上过期”的key,仅在内存达限且有写入时,从已设TTL的key中随机采样(默认20个),淘汰其中ttl最小者;它不主动清理、不全量扫描、不保证命中濒死key。

volatile-ttl 不会“优先删除短有效期的 key”,它只在内存真正触顶且有写入时,从已设 TTL 的 key 中随机采样一批,挑出里面 ttl 值最小的那个删掉——不是全量扫描,不保证精准,也不主动清理。
volatile-ttl 的触发条件比你想的苛刻得多
这个策略根本不会“守着过期时间表等 key 濒死”,它完全被动:
- 必须配置了
maxmemory,且 Redis 当前内存使用 ≥ 该值 - 必须发生写入操作(如
SET、LPUSH),触发freeMemoryIfNeeded()流程 - 只有这时,它才从设置了 TTL 的 key 中随机抽样(默认 20 个),比较它们的
ttl返回值,选最小者淘汰 - 如果这批样本里没有剩余 TTL 很小的 key,或者压根没抽中,那就跳过——哪怕你有 key 只剩 1 秒
ttl 命令返回 -2 或 -1 的 key 都会被 volatile-ttl 忽略
这是最常被误判的一点:volatile-ttl 只处理 ttl > 0 的 key。实际检查时:
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
-
ttl key返回-1→ key 存在但没设过期时间 → 被跳过 -
ttl key返回-2→ key 不存在,或已被惰性/定期删除判定为逻辑过期(尚未物理删除)→ 也被跳过 - 只有返回正整数(比如
5、120)的 key 才进入候选池 - 注意:
PERSIST过的 key、刚EXPIRE但状态未刷新的 key,也可能因ttl暂时不可读而漏掉
想让“快过期”更大概率被清掉,只能调高 hz 或换策略
靠 volatile-ttl 本身做不到“加速濒死清理”,真正可操作的路径就三条:
- 把
hz从默认10提到100:让activeExpireCycle()更频繁执行定期删除,提高过期 key 被随机抽中并清理的概率(代价是 CPU 占用上升) - 业务层配合:用
EXPIREAT或PEXPIREAT统一设较短、可控的绝对过期时间点,再起定时任务跑KEYS pattern+TTL扫描,主动DEL剩余 TTL 极低的 key(生产慎用KEYS) - 改用
volatile-lfu或volatile-lru:以访问热度或最后访问时间为第一维度,TTL 仅作过滤条件——至少能避免长期不访问又快过期的 key 占着内存不走
别指望 volatile-ttl 是个“倒计时监控器”。它本质是个带 TTL 过滤的随机采样器,真正决定谁先走的,是内存压力 + 写入动作 + 随机运气。想稳控清理节奏,得绕开它设计上层机制。

















