根本原因是淘汰动作本身阻塞主线程,尤其在hz过低、存在大key或策略与访问模式错配时,单次淘汰可耗时上百毫秒;lru类策略默认仅采样5个key,热点分散或冷数据多时需反复采样比对,遇大key更易超100ms。

内存满时写入变慢,根本原因不是淘汰策略“没起作用”,而是淘汰动作本身卡住了主线程——尤其是当 hz 太低、大 key 存在、或策略与访问模式错配时,Redis 可能花几十甚至上百毫秒在单次淘汰上,直接拖垮写入延迟。
为什么 allkeys-lru / volatile-lru 写入会突然卡顿
LRU 类策略依赖采样和近似排序,但 Redis 默认只从 5 个随机 key 中选最久未用的(maxmemory-samples 5)。如果实际热点分散、冷数据又多,它就得反复采样+比对,直到凑够足够释放空间的 key。更糟的是:一旦遇到 >1MB 的 String 或含上万字段的 Hash,单次淘汰耗时极易突破 100ms。
- 检查是否存在大 key:
redis-cli --bigkeys,重点关注Biggest string和Biggest hash行 - 确认采样数是否合理:生产环境建议设为
maxmemory-samples 10,太高增加 CPU 开销,太低导致淘汰效率低 - 避免在 LRU 场景下混用长 TTL 和短 TTL key:比如商品详情(TTL 2h)和临时 token(TTL 30m)共存,会干扰访问时间局部性判断
volatile-ttl 在批量过期场景下反而加剧写入延迟
当大量 key 被设成相同 TTL(例如统一用 EXPIREAT 批量设置凌晨 2 点过期),volatile-ttl 会在临近该时间点集中淘汰——这不仅引发缓存雪崩,还会让淘汰逻辑在短时间内高频触发,挤占主线程处理写请求的时间片。
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
- 观察
INFO stats中的expired_keys和evicted_keys是否同步激增;若前者远高于后者,说明过期集中但淘汰跟不上 - 改用随机偏移 TTL:比如基础 TTL 设为 7200s,再加 ±300s 随机抖动,打散过期时间
- 绝对不要在高写入压力时段(如大促前 1 小时)执行全量
EXPIRE操作
allkeys-lfu 看似精准,但默认参数会让写入更慢
allkeys-lfu 要维护每个 key 的访问频次计数器,且默认 lfu-log-factor 10 会让高频访问的 key 长期滞留内存。当内存紧张时,Redis 不得不扫描更多 key 才能找到真正低频的候选者,CPU 占用升高,写入响应自然变长。
- 调低
lfu-log-factor:对电商类业务,建议设为1或2,加快冷 key 衰减速度 - 配合
lfu-decay-time 1(单位:分钟),让计数器每分钟衰减一次,避免历史热度长期绑架淘汰决策 - 注意:如果业务中存在大量无 TTL 的配置项或元数据,
allkeys-lfu会把它们也纳入统计——此时应切回volatile-lfu并确保所有缓存 key 都显式设了 TTL
真正影响写入速度的,从来不是“删不删”,而是“删得有多快、多准”。淘汰策略必须和 hz(建议调至 20)、maxmemory-samples、key 生命周期设计一起调,缺一不可。单独改 maxmemory-policy 几乎没用,反而可能掩盖真实瓶颈。










