慢查询日志虽不记录淘汰事件本身,但触发淘汰的写命令(如SET、HSET)会因主线程执行驱逐逻辑而耗时陡增,从而落入慢日志;需结合INFO memory、evicted_keys增长及maxmemory-policy配置交叉验证。

慢查询日志本身不直接记录内存淘汰事件,但当 maxmemory 触发淘汰时,某些命令会因等待淘汰逻辑而显著变慢——这类延迟会真实落入慢查询日志中,成为关键线索。
为什么淘汰过程会导致慢查询?
Redis 内存淘汰(如 allkeys-lru)不是纯后台行为:当写入触发内存上限,且淘汰策略需要主动驱逐 key 时,主线程必须执行查找、计算、删除等操作。尤其是面对大 key 或高基数集合,LPOP、DEL、EXPIRE 等命令可能突然从微秒级飙升至几十毫秒甚至上百毫秒。
- 淘汰本身不记日志,但“触发淘汰的那条写命令”会被记录——比如
SET或HSET耗时异常高 -
volatile-lfu等策略需遍历过期 key 的访问频次,CPU 开销大,易拖慢后续命令 - 如果淘汰策略是
noeviction,则不会出现此类延迟,但写入会直接返回(error) OOM command not allowed when used memory > 'maxmemory'.
如何从 slowlog get 输出识别淘汰干扰?
执行 slowlog get 10 后,重点比对以下三项:
- 看命令耗时是否集中在
SET、HSET、LPUSH等写命令,而非GET或HGET - 检查这些慢命令的参数长度:若
SET key "very_long_value"中 value 明显超长,说明可能在为新数据腾空间 - 对比时间戳:多个慢日志是否密集出现在同一秒内?这往往是批量写入撞上内存阈值的典型信号
示例中一条日志:1) 1) (integer) 12345 2) (integer) 1734627890 3) (integer) 42800 4) 1) "SET" 2) "user:profile:789" 3) "..." —— 耗时 42.8ms,远超 1ms 阈值,且非 KEYS 或 SORT 等高复杂度命令,大概率是淘汰开销所致。
验证淘汰是否真正在发生
仅靠 slowlog 不足以确认,必须交叉验证:
- 运行
INFO memory,检查used_memory是否持续接近maxmemory,且mem_fragmentation_ratio在 1.0–1.3 之间(排除碎片干扰) - 执行
INFO stats,观察evicted_keys计数是否在增长;若为 0,则淘汰未触发,慢查询另有原因 - 用
CONFIG GET maxmemory-policy确认策略是否为allkeys-*或volatile-*;若为noeviction却仍有慢写入,说明问题不在淘汰本身,可能是大 key 删除阻塞
注意:evicted_keys 是累计值,需在两次采样间做差值判断活跃淘汰频率。
容易被忽略的细节
真正棘手的情况往往藏在组合行为里:比如业务每分钟批量写入 1000 个带 TTL 的 session key,但 maxmemory-policy 设为 volatile-lru,而大部分 key 实际未设置过期时间(TTL 返回 -1),导致淘汰逻辑失效、内存持续上涨,最终某次 SET 触发紧急扫描——此时 slowlog 里看不到高频淘汰,却能看到单条命令耗时陡增。这种“策略与数据特性错配”比单纯内存满更难定位。



















