bigywater.tech
Redis · 21

volatile-lru 淘汰算法

设maxmemory=3MB配合volatile-lru策略,插入无TTL和有TTL两类key直到触发内存淘汰,验证只有设了过期时间的key才会被淘汰。

200/200
无TTL的key100%幸存
516/600
有TTL的key被淘汰了84个
83次淘汰
触发eviction的计数

做的事:内存不够时,两类key分别是什么下场

一类key设了TTL,一类没设,maxmemory给得很紧。

操作CONFIG SET maxmemory-policy volatile-lru CONFIG SET maxmemory 3mb 插入200个persistent_*(无TTL) 插入600个volatile_*(有TTL, ex=10000)

验证:无TTL的key,一个都没被淘汰

内存撑满触发了淘汰,看谁被牺牲了。

结果used_memory: 3143792 字节 (已顶到maxmemory 3145728附近) evicted_keys: 83 persistent_(无TTL) 幸存: 200 / 200 volatile_(有TTL) 幸存: 516 / 600

数字非常直接:200个没设TTL的 persistent_* 一个都没少;600个设了TTL的 volatile_* 少了84个(跟的evicted_keys计数基本吻合)。volatile-lru 只在"设了过期时间的key"这个子集里,按最近最少使用的顺序做淘汰——完全不去碰那些没有TTL的key,不管内存有多紧张。

这就是volatile-lru的语义:"过期时间"在这个策略下被当成了"这个key是可以被牺牲的候选"的标记——业务上认为"重要、必须长期保留"的数据不设TTL,"可以被淘汰腾地方"的缓存类数据设TTL,就能靠这个策略自动实现分级淘汰。如果所有key都没有TTL,volatile-lru会发现无处可淘汰,行为退化成类似noeviction。

分步演示:volatile-lru的淘汰范围

每一步都是本文上面用redis-cli和redis-py跑出来的原始结果。

volatile-lru只淘汰设了TTL的key
这一步新验证的结果

    本文用到的工具

    • 本机 Redis 8.10.1 单节点,maxmemory=3MB
    • CONFIG SET maxmemory-policy volatile-lru:验证淘汰范围只限于有TTL的key
    京ICP备2026067502号-1京公网安备11010502063487号