Redis卡顿主因是内存满时同步驱逐bigkey,导致主线程阻塞;应启用lazyfree-lazy-eviction、改DEL为UNLINK、用--bigkeys定位大key,并依访问模式选allkeys-random或allkeys-lfu淘汰策略。

为什么 SLOWLOG 里全是 SET / DEL 却还卡?
这不是命令本身慢,而是 Redis 在执行这些命令前,被迫同步驱逐(evict)key 来腾内存。当 maxmemory 触顶、又配置了 allkeys-lru 或 volatile-lru 这类需要采样+比对的策略时,每次写入都可能触发一轮淘汰逻辑——尤其遇到 bigkey,释放内存过程会阻塞主线程,直接拖慢后续所有命令。
典型现象:SLOWLOG get 10 显示大量 SET、DEL、HSET 耗时超 10ms,但业务没改,QPS 也没突增;同时 INFO memory 中 used_memory_human 稳定贴近 maxmemory_human。
用 redis-cli --bigkeys 快速定位隐患 key
别等线上报警才扫,定期跑一次就能暴露风险点。注意它默认只采样 0.01% 的 key,对大实例要调低采样间隔避免卡顿:
-
redis-cli -h 127.0.0.1 -p 6379 --bigkeys -i 0.001(更细粒度扫描) - 重点看输出中
Biggest string、Biggest hash行末的字节数,超过 10KB 就该警惕 - 如果发现
list或zset元素数 > 1w,即使单个元素小,也属于逻辑 bigkey,LRANGE/ZRANGE容易触发慢查
lazyfree-lazy-eviction yes 是关键止血项
Redis 4.0+ 默认淘汰是同步释放内存,遇到 bigkey 就卡死。开启后台异步驱逐后,主线程只做标记,真正释放交由 bio 线程处理:
- 确认版本:
redis-cli INFO server | grep redis_version≥ 4.0 - 启用配置:
CONFIG SET lazyfree-lazy-eviction yes(临时生效),并写入redis.conf - ⚠️ 注意:这仅对淘汰策略触发的删除生效,不覆盖
UNLINK或显式DEL行为 - 若业务已大量使用
DEL删除 bigkey,应主动替换成UNLINK(异步删)
淘汰策略选 allkeys-random 还是 allkeys-lfu?
取决于你的数据访问模式是否真有“热度区分”:
-
allkeys-random:完全跳过采样比对,驱逐开销恒定极低,适合缓存命中率本就不高、或写多读少的场景(如 session 存储) -
allkeys-lfu:需开启lazyfree-lazy-eviction才安全,否则高频 LFU 计数器更新+衰减+采样会加重 CPU 压力;适合能明确分出冷热数据的业务(如商品详情页缓存) - 绝对避开
volatile-lru+ 大量短过期 key:过期 key 清理和淘汰逻辑叠加,双重阻塞风险
真正容易被忽略的是:哪怕开了 lazyfree,如果淘汰压力持续高于后台线程处理能力,bio 线程队列会堆积,INFO stats 中 lazyfree_pending_objects 会持续上涨——这时得靠拆实例或升配来根治。


















