# EXPIRE

设置key的生存时间(秒)

语法

EXPIRE key seconds [NX | XX | GT | LT]

  • 从以下版本可用:

    1.0.0

  • 时间复杂度:

    O(1)

  • ACL 类别:

    @keyspace, @write, @fast

key上设置超时。超时后,密钥将自动删除。在Redis术语中,带有相关超时的密钥通常被称为 volatile

只有删除或覆盖密钥内容的命令才能清除超时,包括DEL设置GETSET以及所有*STORE命令。这意味着,所有在概念上“改变”存储在密钥处的值而不将其替换为新值的操作都将保持超时不变。例如,用INCR递增键的值,使用LPUSH将新值推入列表,或使用HSET更改哈希的字段值是所有不影响超时的操作。

也可以清除超时,使用PERSIST将密钥返回为持久密钥命令。

如果使用RENAME重命名密钥,关联的生存时间将转移到新的密钥名称。

如果密钥被RENAME覆盖类似于被诸如RENAME key_B key_A之类的调用覆盖的现有密钥key_A的情况,原始密钥key_A是否具有相关联的超时并不重要,新密钥key_A将继承key_B的所有特性。

请注意,调用EXPIRE/PEXPIRE具有非正超时或EXPIREAT/PEXPIREAT在过去的某个时间将导致密钥被删除而不是过期(相应地,发出的key event将是del,而不是expired)。

# 选项

EXPIRE命令支持一组选项:

  • NX-- 只有当密钥没有过期时才设置过期
  • XX-- 仅当密钥已过期时才设置过期
  • GT-- 仅当新的到期时间大于当前到期时间时才设置到期时间
  • LT-- 仅在新到期时间小于当前到期时设置到期

非易失性密钥被视为无限 TTLGTLT。,GT和选项是互斥的LTNX

# 刷新过期

可以EXPIRE使用已经具有现有过期集的键作为参数来调用。在这种情况下,密钥的生存时间会更新为新值。有许多有用的应用程序,下面的 导航会话模式部分记录了一个示例。

# Redis 2.1.3 之前的差异

在 Redis 2.1.3之前的版本中,使用更改其值的命令更改设置了过期时间的键具有完全删除该键的效果。由于复制层的限制现已修复,因此需要此语义。

EXPIRE将返回 0 并且不会更改设置了超时的键的超时。

# 返回

Integer,具体来说:

  • 1如果设置了超时。
  • 0如果未设置超时。例如,键不存在,或者由于提供的参数而跳过了操作。

# 例子

redis> SET mykey "Hello"
 "OK"
 redis> EXPIRE mykey 10
 (integer) 1
 redis> TTL mykey
 (integer) 10
 redis> SET mykey "Hello World"
 "OK"
 redis> TTL mykey
 (integer) -1
 redis> EXPIRE mykey 10 XX
 (integer) 0
 redis> TTL mykey
 (integer) -1
 redis> EXPIRE mykey 10 NX
 (integer) 1
 redis> TTL mykey
 (integer) 10
  redis> 

# 模式:导航会话

假设您有一个 Web 服务,并且您对 用户最近访问的最近 N 个页面感兴趣,这样每个相邻的页面视图都不会在前一个页面的 60 秒后执行。从概念上讲,您可以将这组页面视图视为用户的导航会话 ,其中可能包含有关他或她当前正在寻找哪种产品的有趣信息,以便您可以推荐相关产品。

您可以使用以下策略在 Redis 中轻松建模此模式:每次用户进行页面查看时,您调用以下命令:

MULTI
RPUSH pagewviews.user:<userid> http://.....
EXPIRE pagewviews.user:<userid> 60
EXEC

如果用户闲置超过 60 秒,则删除该键,仅记录相差小于 60 秒的后续页面浏览量。

这种模式很容易修改为使用计数器使用 INCR 而不是使用列表 RPUSH

# 附录:Redis过期

# 过期的密钥

通常,创建 Redis 密钥时没有关联的生存时间。密钥将永远存在,除非用户以明确的方式将其删除,例如使用 DEL 命令。

命令族能够将EXPIRE过期时间与给定的键相关联,但代价是该键使用了一些额外的内存。当一个键设置了过期时间时,Redis 将确保在指定的时间过去后删除该键。

EXPIRE可以使用and PERSIST 命令(或其他严格相关的命令)更新或完全删除关键生存时间。

# 过期精度

在 Redis 2.4 中,过期可能不是精确的,它可能在零到一秒之间。

从 Redis 2.6 开始,过期错误为 0 到 1 毫秒。

# 过期和持久性

密钥过期信息存储为绝对 Unix 时间戳(在 Redis 2.6 或更高版本的情况下以毫秒为单位)。这意味着即使 Redis 实例不活动,时间也在流逝。

为了使过期工作正常,计算机时间必须保持稳定。如果您从两台时钟严重不同步的计算机上移动 RDB 文件,可能会发生有趣的事情(例如所有加载的密钥在加载时都已过期)。

即使正在运行的实例也会始终检查计算机时钟,因此,例如,如果您将密钥的生存时间设置为 1000 秒,然后将您的计算机时间设置为未来 2000 秒,则该密钥将立即过期,而不是持续1000 秒。

# Redis 如何使密钥过期

Redis 密钥以两种方式过期:被动方式和主动方式。

仅当某些客户端尝试访问密钥时,密钥就会被动过期,并且发现密钥已超时。

当然这还不够,因为有过期的密钥将永远不会被再次访问。这些密钥无论如何都应该过期,因此 Redis 会定期在设置过期的密钥中随机测试几个密钥。所有已经过期的键都会从键空间中删除。

具体来说,这是 Redis 每秒执行 10 次的操作:

  1. 从具有关联过期时间的密钥集中测试 20 个随机密钥。
  2. 删除所有发现过期的密钥。
  3. 如果超过 25% 的密钥过期,请从步骤 1 重新开始。

这是一个简单的概率算法,基本上假设我们的样本代表了整个密钥空间,并且我们继续过期直到可能过期的密钥百分比低于 25%

这意味着在任何给定时刻,使用内存的已过期密钥的最大数量等于每秒最大写入操作量除以 4。

# 复制链接和 AOF 文件中如何处理过期

为了在不牺牲一致性的情况下获得正确的行为,当密钥过期时, DEL 会在 AOF 文件中合成一个操作并获得所有附加的副本节点。这样过期过程集中在主实例中,不会出现一致性错误。

然而,虽然连接到主节点的副本不会独立地使密钥过期(但会等待 DEL 来自主节点的消息),但它们仍将采用数据集中存在的过期的完整状态,因此当一个副本被选为主它时将能够独立地使密钥过期,完全充当主人。

# 历史

  • 从 Redis 版本 7.0.0 开始:添加了选项:NXXX和.GT``LT

# 反馈

如果您在此页面上发现问题,或有改进建议,请提交请求以合并或打开存储库中的问题。

Last Updated: 4/18/2023, 8:45:33 AM