news 2026/10/2 13:59:30

Redis 过期删除和内存淘汰不是一回事:expire、TTL、maxmemory 到底谁负责

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Redis 过期删除和内存淘汰不是一回事:expire、TTL、maxmemory 到底谁负责

Redis 过期删除和内存淘汰不是一回事:expire、TTL、maxmemory 到底谁负责

很多人学 Redis 时,会把两个概念混在一起:

  • key 过期了,Redis 怎么删?
  • Redis 内存满了,Redis 怎么淘汰?

它们看起来都在“删 key”,但解决的问题完全不同。

一句话先分开:

过期删除处理的是:这个 key 到时间了,是否应该失效。
内存淘汰处理的是:Redis 内存不够了,应该牺牲哪些 key 腾空间。

前者和expire/TTL有关,后者和maxmemory/maxmemory-policy有关。

如果这两个概念不分清,面试和排查线上问题都会很容易乱。

过期删除:key 到时间了怎么办

Redis 可以给 key 设置过期时间。

比如:

SET token:1001 abc
EXPIRE token:1001 3600

意思是:

token:1001 这个 key 最多存活 3600 秒。

也可以直接写:

SET token:1001 abc EX 3600

查看剩余时间:

TTL token:1001

返回值大概有三类:

  • 正数:还剩多少秒。
  • -1:key 存在,但没有过期时间。
  • -2:key 不存在。

这里的核心是:Redis 不一定在过期时间到达的那一瞬间立刻删除 key。

它通常结合两种方式:

  • 惰性删除。
  • 定期删除。

惰性删除:访问时发现过期再删

惰性删除很好理解。

当客户端访问某个 key 时,Redis 先检查它是否过期。

如果没过期,就正常返回。

如果已经过期,就删除它,并表现得像 key 不存在。

比如:

GET token:1001

Redis 发现token:1001已经过期,于是删除,然后返回空。

这种方式的优点是简单,不会为了删除过期 key 一直扫描全库。

缺点也明显:如果一个过期 key 再也没人访问,它可能会继续留在内存里一段时间。

所以 Redis 不能只靠惰性删除。

定期删除:后台抽样清理过期 key

Redis 还会周期性地检查一部分设置了过期时间的 key。

注意这里是“一部分”,不是每次把所有 key 都扫一遍。

为什么?

因为 Redis 通常要服务大量请求,如果每隔一段时间就全量扫描所有 key,会造成明显卡顿。

所以 Redis 的策略更像:

定期抽样检查一批带过期时间的 key,发现过期就删除;如果过期比例较高,再继续多扫一点。

这是一种折中:

  • 不让过期 key 永远堆在内存里。
  • 也不为了清理过期 key 把 Redis 主线程拖死。

所以过期删除的本质是:

用惰性删除保证访问正确性,用定期删除控制内存里的过期 key 数量。

内存淘汰:maxmemory 到了怎么办

过期删除不等于内存淘汰。

内存淘汰发生在 Redis 内存达到限制时。

比如配置了:

maxmemory 2gb

当 Redis 使用内存接近或超过这个限制时,如果还要写入新数据,就要根据策略选择一些 key 淘汰掉。

策略由:

maxmemory-policy

决定。

常见策略包括:

  • noeviction:不淘汰,写入直接报错。
  • allkeys-lru:从所有 key 中按 LRU 倾向淘汰。
  • volatile-lru:只从设置了过期时间的 key 中按 LRU 倾向淘汰。
  • allkeys-random:从所有 key 中随机淘汰。
  • volatile-random:只从设置了过期时间的 key 中随机淘汰。
  • volatile-ttl:优先淘汰 TTL 更短的 key。
  • allkeys-lfu:从所有 key 中按 LFU 倾向淘汰。
  • volatile-lfu:只从设置了过期时间的 key 中按 LFU 倾向淘汰。

这里的重点不是背策略名字,而是理解两个维度。

第一个维度:候选范围。

  • allkeys-*:所有 key 都可能被淘汰。
  • volatile-*:只有设置过期时间的 key 可能被淘汰。

第二个维度:淘汰标准。

  • lru:偏向淘汰最近较少使用的 key。
  • lfu:偏向淘汰访问频率较低的 key。
  • random:随机淘汰。
  • ttl:偏向淘汰更快过期的 key。

两者最大的区别

可以放在一张表里看。

对比点过期删除内存淘汰
触发原因key 到期Redis 内存达到 maxmemory
依赖配置expire / pexpire / SET EXmaxmemory / maxmemory-policy
删除对象已经过期的 key策略选中的 key,不一定过期
目标保证过期语义腾出内存
常见机制惰性删除 + 定期删除LRU/LFU/TTL/random/noeviction

最容易误解的一点是:

被内存淘汰的 key 不一定已经过期。

如果配置的是allkeys-lru,一个没有设置过期时间的热点之外 key,也可能因为内存压力被淘汰。

反过来:

已经过期的 key 也不一定在过期瞬间立刻从内存里消失。

它可能等到访问时被惰性删除,或者等后台定期删除抽样扫到。

为什么线上会出现“明明设置 TTL,内存还是高”

这是很常见的问题。

原因可能有几类。

第一,很多 key 没有设置 TTL。

可以抽样检查:

TTL some:key

如果返回-1,说明这个 key 没有过期时间。

第二,过期 key 没有立刻被清掉。

这不一定是 bug。Redis 的过期清理本来就不是“到点全量删除”。

第三,写入速度太快,过期速度跟不上写入速度。

比如大量短 TTL key 持续写入,定期删除虽然一直工作,但内存仍可能上升。

第四,maxmemory 没有限制,或者淘汰策略不符合业务。

如果没有设置maxmemory,Redis 会尽量用系统内存,直到操作系统压力变大。

如果设置了volatile-lru,但很多 key 没有 TTL,那么这些无 TTL key 根本不在淘汰候选范围内。

这就是为什么缓存场景里经常更推荐:

allkeys-lru

因为缓存数据本来就允许被淘汰,候选范围覆盖所有 key,更符合“内存不够就丢缓存”的模型。

排查时看哪些指标

如果你怀疑 Redis 内存或过期策略有问题,可以先看:

INFO memory
INFO stats
CONFIG GET maxmemory
CONFIG GET maxmemory-policy

重点关注:

  • used_memory:Redis 当前使用内存。
  • maxmemory:是否设置内存上限。
  • evicted_keys:因为内存淘汰被删除的 key 数量。
  • expired_keys:因为过期被删除的 key 数量。
  • keyspace_hits/keyspace_misses:命中和未命中情况。

判断思路可以这样走:

如果expired_keys增长,说明过期删除在发生。

如果evicted_keys增长,说明发生了内存淘汰。

如果used_memory很高,但evicted_keys一直是 0,要看是否没配置maxmemory,或者策略是noeviction。

如果maxmemory-policy是volatile-*,但很多 key 没有 TTL,那么内存淘汰范围可能比你想象的小。

面试里怎么回答

如果被问“Redis 过期删除和内存淘汰有什么区别”,可以这样回答:

过期删除是 key 设置了 TTL 后,到期需要失效,Redis 通过惰性删除和定期删除结合处理。惰性删除是在访问 key 时发现过期再删,定期删除是后台抽样清理过期 key。内存淘汰是 Redis 达到 maxmemory 后,为了腾空间按 maxmemory-policy 选择 key 删除,比如 allkeys-lru、volatile-lru、allkeys-lfu 等。过期删除处理时间语义,内存淘汰处理容量压力,被淘汰的 key 不一定过期。

如果继续追问“为什么 key 过期了内存没马上降”,可以这样答:

Redis 不会在 key 过期瞬间全量扫描删除,因为这样成本太高。过期 key 可能等到下一次访问时惰性删除,也可能被后台定期删除抽样清理。所以过期时间保证的是逻辑失效,不保证内存立刻下降。

总结

这两个概念一定要分开:

  • expire/TTL管的是“什么时候失效”。
  • maxmemory-policy管的是“内存不够时丢谁”。
  • 过期删除主要靠惰性删除和定期删除。
  • 内存淘汰主要看maxmemory和maxmemory-policy。
  • expired_keys增长代表过期删除,evicted_keys增长代表内存淘汰。

一句话收尾:

过期删除是时间问题,内存淘汰是容量问题。它们都可能删除 key,但不是同一套机制。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/2 13:59:28

Python开发常见错误Top10,你中了几个?

1. 用可变对象做函数默认参数这是Python最经典的陷阱。def add(item, lst[]): 你以为每次调用都得到新列表,实际上所有调用共享同一个列表。正确做法是用None做默认值,函数内部再初始化。这个错误隐蔽性强,初学者几乎必中。2. 在循环中修改列…

作者头像 李华
网站建设 2026/10/2 13:59:27

贵州设施齐全的悬崖咖啡打卡地有哪些

贵州设施齐全的悬崖咖啡打卡地有哪些——聚焦山野高空的松弛体验指南贵州烽玩家体育发展有限公司,简称烽玩家,是黔南地区专注于户外运动项目开发、运营与文旅融合的服务机构。一句话定位:以荔波喀斯特原生地貌为底色,打造集探洞、…

作者头像 李华
网站建设 2026/10/2 13:58:22

leetcode 1851. Minimum Interval to Include Each Query

Problem: 1851. 包含每个查询的最小区间 深夜做这道题确实挺难的&#xff0c;也是用的优先队列&#xff0c;但是超时了&#xff0c;看了答案的&#xff0c;可以一次遍历就行&#xff0c;不需要重复遍历 Code using pr pair<int, int>; class Solution { public:vector…

作者头像 李华
网站建设 2026/10/2 13:57:00

IIoT 都还没搞明白,EIoT 又来了:一文讲透具身智能物联网与工业物联网的本质区别、产业现状与从业者破局路线

IIoT 都还没搞明白,EIoT 又来了:一文讲透具身智能物联网与工业物联网的本质区别、产业现状与从业者破局路线 核心结论先给你:IIoT(工业物联网)和 EIoT(具身智能物联网)根本不是同一件事的升级版,而是两个不同的物种。IIoT 的本质是"让物会说话"——连接、采集、优化;…

作者头像 李华
网站建设 2026/10/2 13:56:06

多设备适配型电源轨道系统技术选型维度分析

随着用电设备类型日益多元&#xff0c;从手机、无线充电器等低功率数码产品到烤箱、投影仪、生产操作台等大功率设备&#xff0c;传统固定插座在数量、位置与外观集成度上的局限逐步显现。电源轨道系统凭借适配器可灵活配置、取电位置可调的技术特性&#xff0c;成为多设备配电…

作者头像 李华
网站建设 2026/10/2 13:55:20

会编网络:学Python不必死背知识,这些底层小常识才是理解的关键

很多新手在学习的过程中都会陷入一个误区, 他们疯狂地背诵那些语法公式, 记忆各种各样的代码模板, 还会花费大量的时间来进行死记硬背这一类的动作, 可是呢每当他们真正进行实际操作的时候还是不知道从何下手。其实学习这个行为的核心内容从来都不是说要去死记硬背那些语法规则…

作者头像 李华