EXPIREAT、PEXPIREAT:设置过期时间

Redis 用户不仅可以通过设置生存时间来让键在指定的秒数或毫秒数之后自动被移除,还可以通过设置过期时间(expire time),让Redis 在指定UNIX时间来临之后自动移除给定的键。

设置过期时间这一操作可以通过EXPIREAT命令或者PEXPIREAT命令来完成。其中,EXPIREAT命令接受一个键和一个秒级精度的UNIX时间戳为参数,当系统的当前UNIX时间超过命令指定的UNIX时间时,给定的键就会被移除:

EXPIREAT key seconds_timestamp

与此类似,PEXPIREAT命令接受一个键和一个毫秒级精度的UNIX时间戳为参数,当系统的当前UNIX时间超过命令指定的UNIX时间时,给定的键就会被移除:

PEXPIREAT key milliseconds_timestamp

EXPIREAT使用示例

如果我们想要让msg键在UNIX时间1450005000s之后不再存在,那么可以执行以下命令:

redis> EXPIREAT msg 1450005000
(integer) 1

在执行这个EXPIREAT命令之后,如果我们在UNIX时间1450005000s或之前访问msg键,那么Redis将返回msg键的值:

redis> GET msg
"hello world"

如果我们在UNIX时间1450005000s之后访问msg键,那么Redis将返回一 个空值,因为这时msg键已经因为过期而自动被移除了:

redis> GET msg
(nil)

表12-4展示了msg键从设置过期时间到被移除的整个过程。

image 2025 01 05 16 27 55 186
Figure 1. 表12-4 msg键从设置过期时间到被移除的整个过程

PEXPIREAT使用示例

以下是一个使用PEXPIREAT命令设置过期时间的例子,这个命令可以将 number键的过期时间设置为UNIX时间1450005000000ms:

redis> PEXPIREAT number 1450005000000
(integer) 1

在UNIX时间1450005000000ms或之前访问number键可以得到它的值:

redis> GET number
"10086"

而在UNIX时间1450005000000ms之后访问number键则只会得到一个空值,因为这时number键已经因为过期而自动被移除了:

redis> GET number
(nil)

表12-5展示了number键从设置过期时间到被移除的整个过程。

image 2025 01 05 16 29 38 142
Figure 2. 表12-5 number键从设置过期时间到被移除的整个过程

更新键的过期时间

与EXPIRE/PEXPIRE命令会更新键的生存时间一样,EXPIREAT/PEXPIREAT命令也会更新键的过期时间:如果用户在执行 EXPIREAT命令或PEXPIREAT命令的时候,给定键已经带有过期时间,那么命令首先会移除键已有的过期时间,然后再为其设置新的过期时间。

比如在以下调用中,第二条EXPIREAT命令就将msg键的过期时间从原来的1500000000修改成了1600000000:

redis> EXPIREAT msg 1500000000
(integer) 1
redis> EXPIREAT msg 1600000000
(integer) 1

自动过期特性的不足之处

无论是本节介绍的EXPIREAT/PEXPIREAT,还是前面介绍的 EXPIRE/PEXIRE,它们都只能对整个键进行设置,而无法对键中的某个元素进行设置,比如,用户只能对整个集合或者整个散列设置生存时间/过期时间,但是却无法为集合中的某个元素或者散列中的某个字段单独设置生存时间/过期时间,这也是目前Redis的自动过期功能的一个缺陷。

其他信息

  • 复杂度:EXPIREAT命令和PEXPIREAT命令的复杂度都为O(1)。

  • 版本要求:EXPIREAT命令从Redis 1.2.0版本开始可用,PEXPIREAT命令从Redis 2.6.0版本开始可用。