Redis频繁淘汰是亚健康标志,会非线性拖垮QPS并抬高P99延迟;每次淘汰需同步执行LRU/LFU更新、候选池维护、键空间通知等CPU密集操作,导致主线程阻塞、CPU冲高、内存碎片上升及fork失败风险。

Redis频繁触发内存淘汰(evicted_keys 持续增长)不是“缓存不够用”的简单信号,而是系统已进入亚健康状态的明确标志——它会直接拖垮QPS并显著抬高P99延迟,且这种影响是叠加式、非线性的。
evicted_keys > 0 时,Redis实际在做什么
每次淘汰一个key,Redis不仅要释放键值内存,还要:更新LRU/LFU时间戳、维护淘汰候选池、触发键空间通知(如果启用)、可能触发AOF重写或RDB快照的脏页刷新。这些操作都不是纯内存释放,而是同步CPU密集型任务。
- 淘汰本身会阻塞主线程,尤其在
allkeys-lru或allkeys-lfu下,需扫描整个键空间采样,CPU使用率会阶段性冲高 - 若同时开启
notify-keyspace-events,每个被删key都会触发事件广播,进一步放大开销 - 淘汰引发的内存碎片率(
mem_fragmentation_ratio)上升,会导致后续分配更慢,间接拉长命令执行时间
高频驱逐对QPS和P99延迟的实测影响
某电商促销场景中,当 evicted_keys 达到 1200+/s 时,观测到以下现象:
- QPS从稳定 45k 下跌至 28k,降幅达 38%,并非因客户端限流,而是Redis处理吞吐能力被自身淘汰逻辑反向压制
- P99延迟从 18ms 跳升至 142ms,其中 60%以上延迟来自淘汰采样+键删除的串行等待,而非网络或磁盘
- 即使读多写少场景,
GET命中率下降也会导致更多请求穿透到后端,形成数据库QPS雪崩(+210%),反过来又加剧Redis负载
为什么 maxmemory 不是“安全水位线”
maxmemory 是硬阈值,但淘汰真正开始前,Redis内部已有隐性压力:
-
used_memory_rss远高于used_memory(如比值 > 1.5)时,说明碎片严重,即使used_memory未达maxmemory,操作系统内存可能已吃紧,触发Swap或OOM Killer风险 - 淘汰策略生效前,Redis会提前启动“预淘汰”扫描(尤其在
volatile-lru下),这部分工作不计为evicted_keys,但消耗CPU资源 - 后台子进程(如bgsave、aof rewrite)需要fork,而高内存碎片会使fork变慢甚至失败,造成命令阻塞数秒级抖动
高频驱逐本质是缓存治理失效的外在表现——它暴露的是数据生命周期管理缺失、过期策略滥用、或结构选型不合理等深层问题,而不是调大 maxmemory 就能解决的配置问题。


















