Redis里那些过期数据到底咋办,清理还是留着,有啥好办法没?
- 问答
- 2025-12-26 06:18:28
- 2
Redis里的过期数据,说白了就是那些你给它们设置了“保质期”的键值对,时间一到,Redis理论上就应该把它们扔掉,腾出空间给新的数据,那这些过期数据是等着Redis自动清理,还是我们手动干预?有啥好法子能处理得又干净又不影响服务呢?咱们就来详细唠唠。
过期数据不能一直留着,必须清理。

这就像你家的冰箱,吃剩的菜贴了保质期标签,到期了你还不扔,不仅占着地方,时间长了还会发霉变质,影响其他食物,Redis的内存就是那个冰箱,内存是有限的,而且很宝贵,如果过期数据一直堆积着不删除,最终会导致内存耗尽,这时候,Redis就要触发它的“内存淘汰策略”了,根据你设置的策略(比如淘汰最久未使用的键,或者随机淘汰),它可能会删掉一些还没过期的数据来腾地方,这就好比冰箱没空间了,你不得已把一些还没到期的牛奶扔了,反而把过期的剩菜留下了,这显然不是我们想看到的,更糟的是,如果设置的是“不淘汰”策略,那整个Redis就无法再写入新数据,会报错,让过期数据及时被清理,是保持Redis健康高效运行的关键。
Redis是怎么清理这些过期数据的呢?它主要靠两招组合拳:惰性删除和定期删除。 (参考来源:Redis官方文档关于过期机制的描述)

第一招叫“惰性删除”。 这个最好理解,不见棺材不掉泪”,当客户端尝试去访问一个键的时候,Redis才会顺便检查一下这个键是否过期了,如果过期了,当场就把它删掉,然后返回一个空值给客户端,这个策略的优点是直接,对CPU非常友好,因为只在需要的时候才干活,但它的缺点也特别明显:太被动了,如果一个过期键永远不再被访问,那它就永远像个幽灵一样占着内存,成了“内存垃圾”,单靠惰性删除是不够的,必须得有主动出击的机制。
第二招叫“定期删除”。 这是因为惰性删除的不足而存在的补充策略,Redis会每隔一段时间(默认是100毫秒,但会自适应调整)主动抽出一小会儿功夫,从设置了过期时间的键里面,随机抽查一批(默认20个),检查它们是否过期,过期的就删除,如果在这一批中,发现过期键的比例超过25%,它就认为这个“垃圾”有点多,会立即再随机抽一批,继续删,直到过期键的比例降下来为止。(参考来源:Redis源码分析及相关技术博客对定期删除流程的解读)

这个策略的目的是为了减少那些“永远不被访问的过期键”造成的内存浪费,但它是个折衷方案:如果抽检得太频繁或者每次检查太多键,就会消耗太多CPU,影响Redis处理正常命令的性能;如果抽检得太松,又可能清理不及时,导致内存垃圾堆积。
既然Redis有这两种自动机制,那我们是不是就可以高枕无忧了呢?
大多数情况下,是的,Redis的这套组合拳在常规场景下表现不错,但凡事有例外,如果你的业务有以下特点,就可能需要你多操点心:
- 短时间内有海量键同时过期:比如你搞了个活动,给所有用户生成了一个临时优惠券,过期时间都设在同一秒,当这一刻到来时,定期删除任务可能会瞬间面临巨大的检查压力,虽然它会分批做,但依然可能引起短暂的CPU飙升,微秒级别的延迟可能会增加,对于延迟极其敏感的系统,这可能是个问题。
- 存在大量永不访问的过期键:如果你的应用会产生很多“一次性的”数据,并且再也不会被读取,那么惰性删除就失效了,清理压力完全给到了定期删除,如果定期删除的速度赶不上新过期键产生的速度,内存还是会慢慢被这些“僵尸键”占满。
面对这些特殊情况,我们有啥好办法可以优化一下呢?
- 打散过期时间:这是应对大量键同时过期最有效也最简单的办法,不要把所有键的过期时间设成同一个点,你有一万张优惠券要在一小时后失效,不要在创建时都设置
EX 3600,可以给它们加上一个随机数,比如EX 3600 + random(0, 300),让它们的过期时间分散在一小时到一小时零五分钟之间,这样就把清理压力平均分摊开了,避免了“雪崩”。 - 监控与告警:你必须时刻关注Redis的内存使用情况,通过监控工具,查看
used_memory(总内存)和used_memory_rss(进程实际占用物理内存)等指标,更重要的是,关注evicted_keys(因内存不足被淘汰的键数)这个指标,如果这个数字在持续增长,就是一个强烈的警告信号,说明你的内存已经不足,过期数据清理不过来,已经开始删未过期的数据了,这时候你就得赶紧排查原因,是业务量增长太快?还是出现了大量预期外的僵尸键? - 合理配置内存淘汰策略:在Redis配置文件里,
maxmemory-policy这个设置非常重要,通常推荐设置为volatile-lru(从已设置过期时间的键中,淘汰最久未使用的),这样即使定期删除偶尔没跟上,当内存快满时,Redis也会优先从那些“可能不太重要”的过期键集合里找东西删,而不是动不动就删掉那些没有过期时间的关键数据。 - 考虑使用Redis 4.0以上的版本:Redis 4.0引入了一个叫
MEMORY USAGE的命令,可以精确计算一个键及其值占用的内存字节数,这对于你分析到底是哪些大Key或者哪些类型的键占用了大量空间非常有帮助,便于进行针对性的优化。
总结一下:Redis的过期数据,肯定不能留着,必须清理,Redis自己提供的“惰性删除+定期删除”机制是主力军,在大部分时候能较好地工作,我们的任务是为它创造良好的工作条件:一是通过打散过期时间避免集中清理的压力;二是通过密切监控内存和淘汰key的数量,像看汽车仪表盘一样随时掌握Redis的健康状况;三是配置好合适的内存淘汰策略,作为最后一道防线。 这样多管齐下,就能让Redis的内存管理既高效又稳定。
本文由酒紫萱于2025-12-26发表在笙亿网络策划,如有疑问,请联系我们。
本文链接:http://waw.haoid.cn/wenda/68624.html
