Redis volatile-lru 没有淘汰键时先检查什么
Redis 配了 maxmemory-policy volatile-lru,内存到上限后却没有淘汰键,最先要查的不是把 maxmemory-samples 调大,而是候选键有没有过期时间。volatile-lru 只在“带 TTL 的键”里挑最近最少使用者;如果整个实例没有可过期键,它的表现就接近 noeviction,新写入可能收到内存限制错误。
排查顺序应是:确认实际策略和上限 → 用TTL看键是否真的带过期时间 → 检查覆盖写是否抹掉 TTL → 再用INFO判断是否触发过淘汰。
volatile-lru的候选集合不是所有键,而是设置了过期时间的键。TTL返回-1表示键永久存在,返回-2表示键已经不存在。- 纯缓存实例通常更适合
allkeys-lru;混合存储则要先修正 TTL 生命周期。
先确认 Redis 真的在用 volatile-lru
先读运行时配置,不要只看磁盘里的 redis.conf。容器启动参数、托管服务默认值或 CONFIG SET 都可能让实际值不同。
# 读取运行中的策略和最大数据集内存 redis-cli CONFIG GET maxmemory-policy redis-cli CONFIG GET maxmemory # 查看当前内存和统计信息 redis-cli INFO memory redis-cli INFO stats
重点记录 maxmemory_policy、maxmemory、used_memory、used_memory_dataset 和 evicted_keys。如果 maxmemory 是 0,表示没有为数据集设置上限,此时不会因为该阈值启动淘汰。若策略实际是 noeviction,现象也不是“volatile-lru 没找到键”。

TTL 返回值能直接判断有没有淘汰候选
对正在写入的缓存键执行 TTL,它比“我在代码里设置过过期时间”更可靠,因为它反映的是 Redis 当前保存的状态。
# -1:键存在但没有过期时间;-2:键不存在
redis-cli SET cache:user:42 '{"name":"Ada"}'
redis-cli TTL cache:user:42
# 用 EX 让新写入同时建立 TTL
redis-cli SET cache:user:42 '{"name":"Ada"}' EX 300
redis-cli TTL cache:user:42
# 也可以分两次写,但要留意中间窗口
redis-cli SET cache:user:42 '{"name":"Ada"}'
redis-cli EXPIRE cache:user:42 300
如果实例里大量键都返回 -1,volatile-lru 没有候选键是正常结果。TTL 的返回值是秒级整数,剩余时间减少到零后键会被视为过期;不要把一次读取到的 TTL 当成精确的淘汰时间。
覆盖写为什么会让原来的 TTL 消失
最容易漏掉的是缓存续写逻辑:第一次用 SET ... EX 300 建立键,后续为了更新内容却执行了不带过期参数的 SET。这个覆盖写会把键变成永久键,随后它不再属于 volatile-lru 候选集合。
# 第一次写入带 TTL redis-cli SET cache:profile:42 v1 EX 300 # 错误示例:覆盖值时没有保留过期时间 redis-cli SET cache:profile:42 v2 redis-cli TTL cache:profile:42 # 结果通常为 -1 # 修复方式:更新时再次明确设置 TTL redis-cli SET cache:profile:42 v3 EX 300 # 续期语义要单独决定,不要无意中永久续命 redis-cli EXPIRE cache:profile:42 300
在客户端封装层,把“写值”和“过期策略”放在同一个缓存方法里更稳妥。若业务要求只在首次写入时设置过期时间,使用客户端支持的保留 TTL 选项,并在上线前确认该选项的版本和语义;不要凭命令名称猜测。

用 INFO 区分未触发、无候选和淘汰异常
| 观察项 | 说明 | 下一步 |
|---|---|---|
used_memory 未接近 maxmemory | 还没到触发条件 | 先检查上限、复制/AOF缓冲和增长来源 |
| 达到上限,TTL 多为 -1 | volatile 集合为空或太小 | 修复写入 TTL,或评估 allkeys-lru |
evicted_keys 增长 | 已经发生过淘汰 | 观察命中率与被淘汰数据是否符合预期 |
| 新写入报内存限制错误 | 没有足够候选键,或实际策略为 noeviction | 核对运行时策略后再改配置 |
Redis 官方文档还提示,复制或 AOF 场景存在不计入淘汰比较的缓冲内存,因此不能只拿机器总内存和 maxmemory 做简单相减。生产上应保留缓冲空间,并持续观察 mem_not_counted_for_evict 等内存字段。
按数据边界选择修复方式
如果实例同时放缓存和必须保留的业务键,volatile-lru 的价值在于只淘汰有 TTL 的键,但前提是缓存键始终正确设置 TTL。若这是纯缓存实例,永久键本身通常就是写入缺陷,此时可以统一补上过期时间,或评估 allkeys-lru 让所有键都进入 LRU 候选范围。若永久数据与缓存数据都很重要,拆分实例比依赖一条淘汰策略更容易解释和运维。
改策略前先做一轮清单:哪些键允许丢失、哪些键必须保留、写入是否总带 TTL、超限时调用方能否接受错误,以及回源是否有保护。不要因为“没有淘汰键”就直接把所有键改成可淘汰。
常见问题
volatile-lru 会主动给没有 TTL 的键补过期时间吗?
不会。它只从已有过期时间的键中选择候选,不负责改变键的生命周期。
TTL 返回 -2 说明淘汰了吗?
不一定。键可能自然过期、被 DEL 删除,或被淘汰;需要结合 expired_keys、evicted_keys 和应用日志判断。
调大 maxmemory-samples 能解决没有候选键吗?
不能。它只影响 LRU 候选采样近似程度,不能把永久键加入 volatile-lru 的候选集合。
Go 正则 FindStringSubmatch 返回空切片时怎么判断原因
- 上一篇
- Go 正则 FindStringSubmatch 返回空切片时怎么判断原因
- 下一篇
- VS Code settings.json 报错时怎么定位缺失逗号
-
- 数据库 · Redis | 10小时前 |
- Redis RDB 和 AOF 同时开启时如何选择恢复来源
- 470浏览 收藏
-
- 数据库 · Redis | 13小时前 | Redis · lua脚本 · Redis Functions · redis Lua Redis Functions EVALSHA
- Redis Function 和临时 Lua 脚本有什么部署区别
- 326浏览 收藏
-
- 数据库 · Redis | 21小时前 |
- Redis Stream 裁剪时 KEEPREF 和 ACKED 怎么选
- 267浏览 收藏
-
- 数据库 · Redis | 22小时前 | Redis · 故障恢复 · Streams · 消费者组 · 消息重试 · redis 消费者组 XPENDING XAUTOCLAIM Redis Streams
- Redis Streams 怎么用消费者组重试超时未确认消息
- 380浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 485次学习
-
- SuperCLUE
- SuperCLUE是权威的中文大语言模型综合评测基准,涵盖语言理解、知识应用、AI Agent智能体及安全性等12项核心能力。通过多轮对话与客观测试,定期发布榜单与技术报告,为模型研发、优化及行业选型提供科学依据。
- 173次使用
-
- C-Eval
- 深入了解C-Eval中文评估套件,涵盖52个学科与4级难度。本文详解其功能特点、Zero-shot/Few-shot使用方法及代码示例,助您全面评测LLM中文理解与泛化能力。
- 106次使用
-
- AI Prompt Library
- 探索AI Prompt Library免费资源库,涵盖营销、写作及多场景AI提示词。兼容ChatGPT、Claude等工具,一键复制优化输出,提升工作效率。
- 34次使用
-
- LangGPT
- LangGPT是一种受编程语言启发的结构化提示词设计工具,提供双层框架、模块化模板及变量功能,帮助用户高效编写高质量Prompt。该项目已在GitHub免费开源,适用于内容创作、编程辅助等多场景。
- 42次使用
-
- ClickPrompt
- ClickPrompt是一款专为AI提示词编写者设计的开源在线工具,支持Stable Diffusion绘图、ChatGPT对话及GitHub Copilot代码辅助。提供Prompt自动生成、一键运行、社区分享及可视化优化功能,帮助用户高效获取精准AI输出。
- 79次使用
-
- Go与Redis实现分布式互斥锁和红锁
- 2022-12-22 117浏览
-
- Go+Redis实现延迟队列实操
- 2023-02-23 426浏览
-
- 一文搞懂Go语言操作Redis的方法
- 2023-01-07 171浏览
-
- Golang分布式应用之Redis示例详解
- 2023-01-07 113浏览
-
- Go Redis客户端使用的两种对比
- 2022-12-30 195浏览

