bigywater.tech
Redis · 26

淘汰和过期的区别

验证完全禁用淘汰时过期依然正常工作,以及给TTL远未到期的key制造内存压力时它们依然会被淘汰,证明淘汰和过期是两套完全独立的机制。

不设maxmemory
过期依然正常工作
11.5天未到期
远未过期的key也会被淘汰
两套独立机制
共享结果但触发原因完全不同

做的事:分别证明"淘汰"和"过期"互不依赖对方

这两个词经常被混着说,但是两套独立触发的机制。

验证1:完全禁用淘汰,过期还工作吗CONFIG SET maxmemory-policy noeviction CONFIG SET maxmemory 0 -- 彻底不设内存上限,淘汰这个概念完全不存在 SET shortlived v1 PX 200 sleep 0.5秒

验证:完全不设maxmemory,TTL过期依然正常工作

没有内存压力,也就没有"淘汰"这件事可做——但过期不受影响。

结果0.5秒后(TTL 200ms早已过期): EXISTS shortlived → :0(按时消失了)

证明了:TTL过期是一个纯粹的时间驱动机制,跟内存够不够用完全没关系——哪怕整个"淘汰"的概念因为没设maxmemory而压根不存在,过期该发生还是照常发生。

验证2:给远未到期的key制造内存压力,会被淘汰吗

反过来验证:淘汰能不能碰那些TTL还早得很的key。

操作CONFIG SET maxmemory 3mb CONFIG SET maxmemory-policy volatile-ttl 插入1000个key,TTL全部设成999999秒(约11.5天,远没到期)
结果DBSIZE: 702(1000个只剩702个) evicted_keys: 4129

证明了反过来的情况:这1000个key的TTL全都还有11.5天才会到期,一个都没有真正"过期",但内存压力下 volatile-ttl 策略照样把其中298个key删掉了——这是淘汰(因为内存不够用,主动牺牲一些数据),不是过期(时间到了自然消失),虽然最终效果都是"key消失了",触发的原因和路径完全不同。

一句话总结两者的区别:过期是"时间到了,不管内存够不够用,这个key的数据本身已经没有存在的必要了";淘汰是"内存不够用了,不管这个key的数据是不是还有效,先牺牲它腾地方"。两套机制完全独立运作,只是共享同一个最终结果——key从keyspace里消失。理解这个区别,排查"key怎么没了"这类问题时才能判断该往哪个方向查。

分步演示:淘汰和过期是两套独立机制

每一步都是本文上面用redis-cli和redis-py跑出来的原始结果。

过期不依赖内存压力,淘汰不依赖TTL是否到期
这一步新验证的场景

    本文用到的工具

    • 本机 Redis 8.10.1 单节点
    • noeviction(验证过期独立于淘汰)/ volatile-ttl(验证淘汰独立于过期)
    京ICP备2026067502号-1京公网安备11010502063487号