Skip to content
Redis 持久化与性能治理 · 第 2 篇 / 共 4 篇
领域数据与中间件
专题Redis 专题
当前序列Redis 持久化与性能治理
阅读位置第 2 篇 / 共 4 篇当前专题第 3 个序列 / 共 7 个序列

Redis 内存、过期与淘汰策略:为什么明明设置了过期,内存还是会涨

很多 Redis 线上问题,看起来像“容量不够”,但真正往下看通常会发现是:

  • Key 设计有问题
  • 过期策略理解有误
  • 淘汰策略不适合当前业务

先说结论

Redis 内存相关问题,重点通常在三层:

  • Key 本身是否设计合理
  • 过期机制是否符合预期
  • 内存淘汰策略是否和业务匹配

不要把“设置了 TTL”理解成“内存一定会立刻降下来”。

更进一步说:

  • 过期解决的是生命周期
  • 淘汰解决的是到达上限后的取舍
  • 二者都不能替代合理的数据模型设计

一、为什么设置了过期也不代表立刻删除

Redis 的过期删除不是“到点立刻精确回收”的强实时机制。

常见理解可以分两种:

  • 惰性删除:访问到这个 Key 时发现过期,再删除
  • 定期删除:后台周期性抽样清理过期 Key

这意味着:

  • 已经过期的 Key,短时间内仍可能存在内存中

所以“设置过期了为什么内存没立刻掉”并不奇怪。

尤其是在:

  • 过期 key 很多
  • 访问分布不均
  • 实例负载较高

的情况下,这种体感会更明显。

二、真正该先关注的是什么

1. 有没有大 Key

即使都设置了过期,只要单个 Key 特别大,内存压力依然会很明显。

2. 有没有无上限增长结构

例如:

  • 不断 append 的列表
  • 不断膨胀的 Hash / Set / ZSet

3. 过期时间是不是设计得过于集中

大量 Key 在同一时刻过期,会放大波动。

4. 是否存在根本不该进 Redis 的数据

很多内存膨胀问题,本质不是 TTL 没配,而是把过多长尾、低价值、低命中数据也塞进缓存了。

三、内存淘汰策略为什么很关键

当 Redis 达到 maxmemory 上限后,是否还能继续写,取决于淘汰策略。

常见思路可以粗略理解为:

  • 不淘汰,直接报错
  • 优先淘汰设置了过期时间的 Key
  • 淘汰最近最少使用或最不常用的 Key
  • 在所有 Key 中做 LRU / LFU 类淘汰

最关键的不是记名字,而是想清楚:

  • 你的 Redis 是纯缓存
  • 还是还承载了必须保留的业务状态

这两个场景,淘汰策略往往不一样。

因为淘汰不是技术动作,而是业务取舍:

  • 是宁可命中率下降
  • 还是宁可写入失败
  • 还是绝不能误删关键状态

四、为什么 TTL 集中过期很危险

如果一大批 key 都在相近时间过期,会同时带来几类问题:

  • 命中率瞬间下滑
  • 回源请求陡增
  • 热点 key 重新构建带来抖动

所以更稳的做法通常是:

  • TTL 加随机抖动
  • 热点数据做分层缓存
  • 重要缓存做预热或提前刷新

五、纯缓存场景更适合什么思路

如果 Redis 主要承载的是:

  • 热点缓存
  • 可丢失临时数据

那么更适合的往往是:

  • 配合过期时间
  • 再加适合的 LRU / LFU 类淘汰策略

因为这类数据本来就允许被替换。

六、如果 Redis 里放了关键状态怎么办

例如:

  • 登录态
  • 防重 token
  • 分布式锁状态

这时就不能简单把它当“可随便淘汰的缓存”。

否则到了内存上限,问题会从“命中率下降”变成“业务逻辑异常”。

这类场景更应该先做的是:

  • 隔离实例
  • 严格容量规划
  • 避免和纯缓存混用淘汰语义

七、排查内存问题时,信息要看成一组

真正排查时,最好把下面几类信息放一起看:

  • used_memory 增长趋势
  • key 数量增长趋势
  • 大 key 分布
  • TTL 分布
  • evicted_keys
  • hit / miss 变化

单看其中一个指标,很容易误判。

八、排查 Redis 内存问题更实用的顺序

第一步:先看内存增长速度

先判断是:

  • 持续缓慢上涨
  • 突然快速飙升

第二步:找大 Key 和热点结构

重点关注:

  • 哪些业务 key 空间增长最快
  • 哪类结构最容易膨胀

第三步:看 TTL 分布

确认:

  • 是否很多 Key 没设置过期
  • 是否 TTL 过于集中

第四步:看淘汰和命中情况

确认:

  • 是否频繁触发淘汰
  • 命中率是否下降明显

九、几个特别容易踩的坑

1. 把 Redis 当无限容量缓存

没有容量边界和淘汰策略,最终一定会出内存问题。

2. TTL 全部设置同一个值

这很容易造成一波集中失效。

3. 以为淘汰策略会“自动帮你兜住所有问题”

淘汰策略只能在内存满时做最后选择,不能替代合理的 Key 设计。

4. 关键状态和可丢缓存混用一套淘汰规则

这是线上非常常见、也非常危险的设计。

一句话总结

Redis 内存治理的关键,不是只盯着“有没有设置过期”,而是同时看:

  • Key 设计
  • 过期分布
  • 大 Key 风险
  • 淘汰策略与业务匹配度

当这几层都想清楚后,很多“Redis 怎么总是涨内存”的问题才会真正变得可控。

延伸阅读相关文章优先当前专题,再补跨专题关联。
同一序列 · 顺着当前主线继续读Redis 大 Key 和热 Key 怎么排查适合把持久化、内存淘汰、大 Key 和热 Key 这类稳定性问题集中来看。Redis 专题 · Redis 持久化与性能治理同一序列 · 顺着当前主线继续读Redis 热 Key 治理适合把持久化、内存淘汰、大 Key 和热 Key 这类稳定性问题集中来看。Redis 专题 · Redis 持久化与性能治理同专题其他序列 · Redis 高可用、过期与性能治理过期键删除策略为什么会影响 RT适合把复制、故障切换、槽迁移、内存碎片和冷启动预热放在一条 Redis 稳定性主线上看。Redis 专题 · Redis 高可用、过期与性能治理同专题其他序列 · Redis 可用性与热点治理细节缓存穿透治理怎么做更稳适合把 Sentinel、穿透防护、延迟队列和地理位置搜索放在一起看。Redis 专题 · Redis 可用性与热点治理细节跨专题关联 · 同场景:基础学习@Conditional 系列注解怎么配合使用适合把自动装配、条件装配、Profile 和循环依赖放回 Spring Boot 启动过程里理解。Spring 专题 · Spring Boot 启动、装配与配置跨专题关联 · 同场景:基础学习保留策略和日志压缩适合哪些场景适合把副本机制、acks、批量压缩和日志组织放在一条 Kafka 投递主线上理解。Kafka 专题 · Kafka 投递链路与日志存储机制
继续阅读Redis 持久化与性能治理当前序列第 2 篇 / 共 4 篇当前专题第 3 个序列 / 共 7 个序列
往前看
上一篇Redis 持久化怎么选回到当前序列上一章上一序列Redis 缓存一致性与更新策略从第 1 篇开始:Redis 缓存更新策略
往后看
下一篇Redis 大 Key 和热 Key 怎么排查继续当前序列下一章下一序列Redis 进阶数据模型与业务场景从第 1 篇开始:Redis String、List、Set、ZSet 怎么做业务建模

把零散经验整理成可查、可复用、可持续更新的企业级知识门户