Redis的LRU淘汰策略坑了我一整天

  • "为什么设置了maxmemory,Redis还是把机器内存吃满了?" * 上周四凌晨,我们的实时风控系统突然告警------主节点内存占用突破80%,触发了k8s的OOM Killer。紧急回滚后排查发现,罪魁祸首竟是那个我以为早就吃透的volatile-lru策略。这里面的水,比想象中深得多。

问题现场:诡异的缓存堆积

场景是这样的:一个日均QPS 3w+的风控服务,用Redis缓存规则引擎的中间计算结果。所有key都设置了24小时TTL,内存上限配置了10GB(maxmemory 10gb),淘汰策略是经典的volatile-lru。按常理,当内存不足时Redis应该优先淘汰最久未使用的带过期时间的key,对吧?

但监控显示,在流量高峰时,Redis内存占用直接冲到了15GB(物理机内存上限)。更诡异的是,redis-cli info显示的evicted_keys竟然是0------这意味着根本没有发生预期中的LRU淘汰!

撕开LRU的伪装

翻遍Redis源码后,我发现了这个反直觉的设计:Redis的LRU根本不是传统意义上的LRU,而是近似LRU。两者的关键区别在于:

  1. 采样淘汰:Redis每次随机选5个(默认)key,淘汰其中最久未使用的那个,而不是全局扫描。这意味着最该被淘汰的key可能根本不在采样范围内。
  2. 懒惰处理:淘汰只在写操作且内存超限时触发,后台不会主动清理。如果写入量突然激增,可能来不及淘汰就OOM了。
  3. TTL优先级陷阱 :volatile-lru只从设了过期时间的key里淘汰,但如果这类key占比不足(比如我们系统中只有60%的key有TTL),LRU池子会越来越小。
shell 复制代码
# 用这个命令能看到真实的内存瓶颈点
redis-cli --bigkeys
# 对比内存超限前后的key分布变化
redis-cli info stats | grep evicted

压测数据打脸

为了验证,我用memtier_benchmark做了组对比测试:

策略 内存超限后淘汰速度 最大内存溢出量 性能损耗
volatile-lru 2k keys/s 23% 8%
allkeys-lru 8k keys/s 5% 15%
volatile-ttl 5k keys/s 12% 11%

看到没?volatile-lru在内存压力下的表现是最差的。你以为设置了TTL就安全了?当带过期时间的key只占总量的60%时,相当于你用40%的内存空间换来了虚假的安全感。

正确姿势与血泪清单

这是我的最终修复方案:

java 复制代码
// 错误:依赖Redis自动淘汰
redisTemplate.opsForValue().set(key, value, 24, TimeUnit.HOURS);

// 正确:双重保险 + 监控
if (redisTemplate.getRequiredConnectionFactory().getConnection().info("memory").get("used_memory").compareTo(maxMemory) > 0) {
    log.warn("Redis memory pressure detected");
    triggerManualCleanup(); // 主动清理冷数据
}
redisTemplate.opsForValue().set(key, value, randomTTL(18, 24), TimeUnit.HOURS); // 避免同时过期
  • 避坑指南:*
  1. 别假设volatile-lru会及时生效------当带过期key占比<90%时,考虑切到allkeys-lru
  2. 监控used_memory和evicted_keys的比值,前者达到maxmemory的90%就该告警
  3. 避免批量写入相同TTL的key,用随机过期时间分散淘汰压力
  4. 在客户端实现二级防护(如上面的Java代码),别把命运全交给Redis

你以为这就完了?

最讽刺的是,当我翻遍文档才发现,官方早在性能优化建议里写过:

"当需要严格限制内存使用时,allkeys-lru通常比volatile-lru更可靠"

可惜这条提示淹没在配置说明的第七段。你看,有时候最贵的学费不是不懂,而是"自以为懂"。

你在用Redis淘汰策略时栽过哪些跟头?欢迎分享你的战争故事。

相关推荐
2分钟速写快排1 小时前
孔乙己的茴字有多少种写法?|AI 对话实时通信的三种实现
前端·javascript·github
AllData公司负责人2 小时前
AI大模型数据开发底座系列说明书,AllData集成Chat2DB开源项目建设AI 数据库分析底座,涵盖AI 洞察/对话SQL/智能视图!
数据库·人工智能·sql·开源·ai 洞察·对话sql
码事漫谈3 小时前
我花了一周时间,看AI公司怎么"管"AI,结果越看越后背发凉
后端
Penge6663 小时前
JavaScript:BOM 详解
前端
泯泷4 小时前
让 Agent 分清“马上办、等一等、顺手办”
人工智能·llm·agent
Penge6664 小时前
Vite vs Webpack:前端构建工具原理与实战
前端
Penge6664 小时前
前端包管理工具:npm、Yarn、pnpm 快速入门
前端
鲜于言悠9054 小时前
Claude Fable 5.2 登场,专治复杂推理与长任务
人工智能
Penge6664 小时前
Sass 了解
前端
Penge6664 小时前
Webpack 打包从 0 到 1 实战笔记
前端