不能直接用redis-benchmark测淘汰策略,因其默认写入无TTL的key,导致volatile类策略退化为noeviction并报OOM错误;真实验证需设maxmemory、确认maxmemory-policy、检查内存碎片率,并分批写入带30–300秒TTL的key至内存达85%阈值后持续施压,观察evicted_keys稳步上升。

为什么 redis-benchmark 不能直接测淘汰策略
因为 redis-benchmark 默认不带 TTL,所有 key 都是永不过期的。你设了 volatile-lru,它却狂塞无过期时间的 key,策略直接退化成 noeviction,一写就报 (error) OOM command not allowed when used memory > 'maxmemory'——这不是策略失效,是测试方法错了。
压测前必须确认的三个配置项
90% 的“策略没起作用”结论都源于没现场验证这三项:
-
CONFIG GET maxmemory:必须不是 0,否则根本不会触发淘汰;建议设为物理内存的 70%~80% -
CONFIG GET maxmemory-policy:运行时值可能被运维脚本覆盖,不能只信配置文件 -
INFO memory | grep mem_fragmentation_ratio:若 >1.5,说明内存碎片严重,即使evicted_keys上升,新写入仍可能失败
构造真实压力数据的三步实操法
目标不是压 QPS,而是让 Redis 内存稳定逼近 maxmemory,同时确保淘汰逻辑真正参与决策:
- 预热阶段:用 Lua 脚本或 Python 批量写入 10 万 key,全部带
SETEX key 60 value(TTL 设 30–300 秒),填到used_memory_human达maxmemory的 85% 左右 - 稳态施压:开启持续写入流(如每秒 200 个新 key),其中混入高频读 key(模拟热 key)和只写不读 key(模拟冷 key)
- 观察信号:紧盯
INFO stats | grep evicted_keys是否稳步上升;若expired_keys远高于evicted_keys,说明自然过期扛了大部分压力,淘汰策略实际未承压
如何对比不同策略的实际效果
别只看最终 QPS 或内存回落速度——那可能是过期释放的假象。重点比三组指标在相同压测条件下的变化趋势:
- 对
allkeys-lru和allkeys-lfu:监控keyspace_hits / (keyspace_hits + keyspace_misses)(命中率),LFU 在热点明确时通常高 5–15% - 对
volatile-ttl:检查evicted_keys增长是否集中在 TTL 剩余 SCAN 抽样验证) - 对
volatile-lruvsallkeys-lru:若业务中大量 key 本就不设 TTL(如分布式锁、计数器),前者会完全跳过它们,导致淘汰不充分,evicted_keys滞涨甚至为 0
最易被忽略的是:淘汰策略生效的前提是内存真到了临界点,而不是“看起来快满了”。used_memory_human 必须稳定卡在阈值 ±50MB 内,且 evicted_keys 每分钟增长不少于 1000,才算进入有效验证窗口。


















