当前位置:首页 > 问答 > 正文

想知道Redis里键怎么设置过期时间吗,教你一步步搞定这个操作

想知道Redis里键怎么设置过期时间吗,教你一步步搞定这个操作 参考自Redis官方文档以及《Redis实战》等常见技术书籍)

其实给Redis里的键设置过期时间,这个操作特别常用,也特别简单,想象一下,你往Redis这个高速仓库里放了一些数据,比如一个临时的验证码,或者一份缓存的热门文章,你肯定不希望这些数据永远占着地方,最好是让它们在一定时间后自动消失,就像给它们定了个“保质期”,Redis提供的这个“设置过期时间”的功能,就是为了解决这个问题的。

核心命令:EXPIRE 和 PEXPIRE

最直接、最常用的命令就是 EXPIRE,它的用法非常直观,假设你已经设置了一个键,mykey,它的值是 “hello”,现在你想让它在60秒后自动过期,那么你只需要执行一条命令:

EXPIRE mykey 60

执行后,Redis会返回一个整数 (integer) 1,这个 1 就表示设置成功,如果键不存在,它会返回 (integer) 0 表示设置失败。

时间单位是秒,这对大多数场景来说已经够用了,但如果你需要更精确的控制,比如以毫秒为单位呢?别担心,Redis还提供了 PEXPIRE 命令,它的用法和 EXPIRE 一模一样,唯一的区别是它的时间单位是毫秒,如果你想设置 mykey 在60000毫秒(也就是60秒)后过期,命令就是:

PEXPIRE mykey 60000

设置键的同时就指定过期时间

你可能会想,我能不能在第一次设置键值的时候,就直接把过期时间也带上呢?这样就不用先 SETEXPIRE,分两步走了,答案是肯定的,而且Redis给了你好几种方法。

  1. SET 命令的扩展参数 这是最推荐的方式,因为一步到位,而且是原子操作(意味着不会出现设置了值却没来得及设置过期时间的情况),Redis的 SET 命令功能非常强大,除了设置值,还可以通过附加参数来设置过期时间。

    • 以秒为单位:使用 EX 参数。
      SET mykey "hello" EX 60

      这条命令的效果和先 SET mykey "hello"EXPIRE mykey 60 是完全一样的,但只用了一条命令。

    • 以毫秒为单位:使用 PX 参数。
      SET mykey "hello" PX 60000
  2. SETEX 命令 这是一个专门为“设置值并指定秒级过期时间”而生的命令,它的参数顺序是 SETEX key seconds value,所以上面的例子用 SETEX 写就是:

    SETEX mykey 60 "hello"

    它和 SET key value EX seconds 的效果是等价的,这个命令的历史更久远一些,很多人习惯用它。

  3. PSETEX 命令 顾名思义,这是 SETEX 的毫秒版本,用法是 PSETEX key milliseconds value

    想知道Redis里键怎么设置过期时间吗,教你一步步搞定这个操作

    PSETEX mykey 60000 "hello"

如何查看键的剩余生存时间

设置完过期时间后,你可能会想知道这个键到底还能活多久,这时候就需要用到查看生存时间的命令。

  • TTL 命令:这个命令返回的是以秒为单位的剩余生存时间。 你只需要执行 TTL mykey

    • 如果键没有设置过期时间,它会返回 (integer) -1
    • 如果键已经过期被删除了,或者键根本不存在,它会返回 (integer) -2
    • 如果键存在并且有过期时间,它会返回一个大于0的整数,(integer) 55,表示还剩55秒。
  • PTTL 命令:这是 TTL 的毫秒版本,返回的是以毫秒为单位的剩余时间,返回值的情况和 TTL 类似。

取消过期时间,让键永久有效

你给一个键设置了过期时间,但中途改变主意了,想让它变成永久有效的,该怎么办?Redis提供了 PERSIST 命令。

mykey 原本设置了过期时间,你执行:

想知道Redis里键怎么设置过期时间吗,教你一步步搞定这个操作

PERSIST mykey

如果操作成功,它会返回 (integer) 1,这样 mykey 就变成了一个永久的键,除非你手动删除它,否则它会一直存在,如果键本来就没有设置过期时间或者不存在,它会返回 (integer) 0

过期键是如何被Redis处理的?

你可能会好奇,到了过期时间的键,Redis是怎么把它们清理掉的呢?Redis使用了两种主要的策略(参考自《Redis设计与实现》):

  1. 惰性删除:当客户端尝试访问一个键时,Redis会先检查这个键是否已经过期,如果过期了,Redis会立刻删除它,然后返回空值,就像这个键从来不存在一样,这种方式的好处是节省CPU,只在访问时才做检查,但坏处是如果很多过期的键永远不被访问,它们就会一直占用内存。

  2. 定期删除:为了弥补惰性删除的不足,Redis会定期地(默认是每100毫秒检查一次)随机抽取一部分设置了过期时间的键,检查它们是否过期,如果过期了就删除,通过限制执行的时长和频率,这种方式可以减少对CPU时间的影响,同时也能及时清理掉大部分过期键。

这两种策略配合使用,就在CPU时间和内存占用之间取得了一个很好的平衡。

实际应用中的小贴士

  • 过期时间只能设置为整数:你不能设置一个浮点数,EXPIRE mykey 5.5 是不行的。
  • 更新值不会影响过期时间:如果你用一个新值覆盖了某个键(比如再次执行 SET mykey "new value"),那么它之前设置的任何过期时间都会被清除,这个键将变成永久的,除非你重新为它设置过期时间。
  • 过期精度不是绝对的:由于Redis的过期删除机制(尤其是定期删除),一个键在过期后可能不会立刻被移除,会有短暂延迟(通常在一秒以内),对于绝大多数应用场景,这个延迟是可以接受的。

好了,以上就是关于在Redis中给键设置过期时间的全部核心操作,从最基础的 EXPIRE,到一步到位的 SET ... EX,再到查看和取消过期,整个过程就像给数据贴上不同时效的标签,非常灵活和强大,多练习几次,你就能完全掌握这个在日常开发中极其重要的技巧了。