Redis里那些让键失效的命令到底有哪些,怎么用才对啊?
- 问答
- 2026-01-03 14:53:14
- 5
你问的这个问题非常实际,就是想知道在Redis里,有哪些办法能让一个键值对“消失”或者“过期”,以及怎么用才不容易出错,这事儿确实不能瞎用,用错了可能会导致数据乱套或者内存泄漏,下面我就把这几条命令和它们的使用场景、坑点给你捋清楚。
第一大类:直接删除,简单粗暴
最干脆的命令就是 DEL,这个命令没啥好说的,就是永久性地删除一个或多个键,数据立刻就没了,找不回来,用法也简单:DEL key1 key2 key3 ...,比如你有个键叫 user:1001:profile,想删了它,就执行 DEL user:1001:profile。
什么时候用 DEL 最合适?
当你非常确定这个数据再也不需要了,或者在进行一些明确的清理操作时,用户主动注销了账号,那你就可以用 DEL 把他相关的数据彻底抹掉。
DEL 的坑点:
它太直接了,不管这个键现在有没有被别的客户端在访问,说删就删,如果在高并发场景下,你刚删掉,另一个程序可能正准备读取它,就会读到个 nil(空),导致程序出错,所以用 DEL 要心里有数,知道自己在干什么。
第二大类:设置过期时间,让Redis自动清理
这是Redis最核心、最常用的功能之一,它允许你给键设置一个“寿命”,时间一到,Redis会自动帮你删除它,这特别适合用来做缓存、验证码、临时会话等场景,主要命令有三个:
EXPIRE key seconds:这是最基础的,给一个已经存在的键设置多少秒后过期,你设置一个验证码SET captcha:123456 "ABCD",然后想让它5分钟后失效,就接着执行EXPIRE captcha:123456 300。PEXPIRE key milliseconds:和EXPIRE一模一样,只是时间单位是毫秒,用于需要更精确控制过期时间的场景。PEXPIRE captcha:123456 300000效果和上面一样。EXPIREAT key timestamp和PEXPIREAT key milliseconds-timestamp:这两个命令不是设置一个“时间段”,而是设置一个具体的“时间点”(Unix时间戳)。EXPIREAT用秒级时间戳,PEXPIREAT用毫秒级时间戳,你想让一个键在今天中午12点整过期,可以先算出12点的Unix时间戳,EXPIREAT key 1716772800。
更方便的写法:
在设置键值的同时直接设置过期时间,一步到位,这样可以避免先 SET 再 EXPIRE 之间的时间差导致的不一致风险。
SETEX key seconds value:相当于SET+EXPIRE。SETEX captcha:123456 300 "ABCD"。PSETEX key milliseconds value:毫秒版本的SETEX。- 在Redis 2.6.12之后,
SET命令本身也增加了过期选项:SET key value EX seconds或者SET key value PX milliseconds,这是现在最推荐的写法,因为SET命令功能最全。SET captcha:123456 "ABCD" EX 300。
设置过期时间的坑点:
- 关键命令返回值的理解:
EXPIRE、PEXPIRE这些命令执行后,会返回一个数字:1表示成功设置了过期时间;0表示失败,失败的主要原因是你指定的key根本不存在,所以你不能想当然地认为命令执行了就万事大吉,最好检查一下返回值,确保键是存在的。 - 持久化带来的不确定性:Redis的数据可以持久化到硬盘上,如果设置了一个键5秒后过期,结果3秒时Redis重启了,重启后Redis从硬盘加载数据,它会检查键的过期时间,如果距离过期还剩2秒,那么加载后2秒这个键会失效,但如果你用了RDB持久化(快照),而键在快照之后才被设置,且在下一次快照之前就过期了,那么这个键可能永远不会被持久化,重启后就彻底没了,这个细节需要根据你的持久化策略来考量。
- 内存淘汰策略的干扰:当Redis内存满了的时候,它会根据你配置的
maxmemory-policy来淘汰一些键,为新的数据腾地方,即使你设置的过期时间还没到,这些键也有可能被提前删除掉,比如用了allkeys-lru策略,Redis会优先淘汰最久未使用的键,不管它过没过期。
第三大类:先获取再删除,保证原子性
这是一个非常有用但容易被忽略的命令:GETDEL(Redis 6.2.0版本引入),它的动作是:获取指定键的值,然后立即删除这个键,这个操作是原子性的,意味着在执行过程中不会被其他命令打断。
什么时候用 GETDEL?
经典场景就是“一次性”消费,你用一个Redis的List实现一个任务队列,生产者用 LPUSH 放任务,消费者用 RPOP 取任务,但传统的 RPOP 有个问题:你取到任务后,如果处理任务的过程中程序崩溃了,这个任务就永远丢失了(因为它已经被从队列里移除了),为了解决这个问题,人们发明了更复杂的机制。
而 GETDEL 提供了一种更简单的“一次性令牌”解决方案,你生成一个限流令牌放在Redis里,客户端来申请令牌时,使用 GETDEL token:api,这个命令能确保:
- 只有能拿到值的客户端,才成功消费了这个令牌。
- 只要拿走了令牌,这个令牌就立刻消失,绝对不会被第二个客户端重复拿到。
这就完美实现了一个简单、安全的一次性消费机制。
GETDEL 的坑点:
最主要的就是版本要求,需要Redis 6.2.0或以上,如果你的Redis版本比较老,就用不了。
总结一下怎么用才对:
- 想永久的、坚决的删除:用
DEL,但要小心并发问题。 - 想让数据活一段时间后自动消失(最常见):优先使用
SET key value EX seconds这种写法,一步到位,最安全,其次考虑SETEX,对于已存在的键,用EXPIRE,但别忘了检查返回值确认键存在。 - 想实现“一次性”读取并消费:如果Redis版本够,果断用
GETDEL,这是最优雅的方式。
无论用哪种方法,都要结合你的业务逻辑、Redis的持久化配置和内存淘汰策略一起来考虑,这样才能真正用得“对”。(参考资料:Redis官方文档中对 Key expiration 以及 DEL, EXPIRE, SETEX, GETDEL 等命令的说明)

本文由度秀梅于2026-01-03发表在笙亿网络策划,如有疑问,请联系我们。
本文链接:http://waw.haoid.cn/wenda/73761.html
