monitor和keys *无法捕获淘汰删除,因淘汰是servercron()中后台行为,不走命令分发路径;真正可用监控手段为info内存轮询、notify-keyspace-events(仅限过期)、aof重写比对及延迟分析。

为什么MONITOR和KEYS *无法捕获淘汰删除
淘汰不是客户端发起的命令,而是 Redis 主线程在 serverCron() 中主动触发的后台行为,不会走命令分发路径。所以 MONITOR 看不到 DEL 操作,KEYS * 也查不到“刚被删但还没来得及同步”的 key——它已经不在数据库字典里了。你看到的只是结果:内存下降、evicted_keys 计数器递增、客户端收到 (error) OOM command not allowed when used memory > 'maxmemory'. 这类错误。
真正可用的监控手段只有两个:INFO + 日志 + 脚本聚合
Redis 不提供“淘汰时记录 key 名”这种粒度的日志,但可通过以下组合逼近目标:
- 开启
notify-keyspace-events并配置为Ev(仅事件通知),但注意:它只通知expired事件,不通知evicted—— 淘汰和过期是两套机制,别混用 - 必须启用 AOF(
appendonly yes),并设aof-rewrite-incremental-fsync yes;淘汰本身不写 AOF,但 AOF 重写时会跳过已淘汰的 key,对比重写前后 AOF 文件可反推“哪些 key 消失了”,代价高、非实时、仅适合事后审计 - 最实用的是轮询
INFO memory:每 1–2 秒执行一次,提取evicted_keys和used_memory_human,计算差值。若evicted_keys每秒增长 >500,说明淘汰正在高频发生,此时立刻redis-cli --scan --pattern "*" | xargs -n 1 redis-cli ttl抽样检查剩余 key 的 TTL 分布,辅助判断是否误配了volatile-lru却混存了大量永不过期 key
CONFIG GET maxmemory 和 CONFIG GET maxmemory-policy 必须先确认
很多线上问题根本不是“怎么监控淘汰”,而是压根没配对策略。常见踩坑点:
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
-
maxmemory为 0(即不限制)→ 淘汰永远不会触发,evicted_keys永远是 0 -
maxmemory-policy是noeviction→ 内存满时直接报错,不删 key,evicted_keys也不会动 - 策略设成
volatile-ttl,但所有 key 都没设过期时间 → 实际等效于noeviction,写入失败却不报警 - 用
allkeys-lru却把 session 和缓存混合存,导致活跃用户 key 被误淘汰
淘汰耗时压力要靠 redis-cli --latency-history 捕获
INFO memory 只告诉你“删了多少”,但不告诉你“删得多慢”。真正影响服务响应的是淘汰动作挤占主线程的时间。运行:
redis-cli --latency-history -i 1
观察输出中是否频繁出现 eviction 类型延迟尖峰(如单次 >10ms)。如果出现,说明:
- 当前
hz值(默认 10)太低,淘汰检查间隔拉长,积压太多待淘汰 key,单次扫描压力陡增 -
active-expire-effort被调到 10,且过期 key 比例长期 >10%,导致每轮serverCron()都反复采样,CPU 占用飙升 - 内存碎片率高(
mem_fragmentation_ratio > 1.5),jemalloc释放后 OS 没回收,淘汰后内存不降反升,形成恶性循环
这些信号比“删了哪个 key”更关键——毕竟你通常不需要知道具体 key 名,而是需要判断:是不是该扩容、换策略,或者拆分业务数据。










