EXPIRE

语法
EXPIRE key seconds [NX | XX | GT | LT]
自版本可用
Redis 开源版 1.0.0
时间复杂度
O(1)
ACL 分类
@keyspace, @write, @fast,

key 设置超时时间。超时时间到期后,该 key 将被自动删除。在 Redis 术语中,具有关联超时的 key 通常被称为 易失的 (volatile)

超时时间仅会被删除或覆盖 key 内容的命令清除,包括 `DEL``SET``GETSET` 以及所有 *STORE 命令。这意味着所有在概念上 修改 key 中存储的值而不将其替换为新值的操作,将保留超时时间不变。例如,使用 `INCR` 增加 key 的值,使用 `LPUSH` 将新值推入列表,或使用 `HSET` 修改哈希字段的值,这些操作都不会影响超时时间。

超时时间也可以使用 `PERSIST` 命令清除,将 key 恢复为持久 key。

如果使用 `RENAME` 重命名 key,则关联的生存时间将转移到新的 key 名称上。

如果 key 被 `RENAME` 命令覆盖,例如现有 key Key_A 被调用 RENAME Key_B Key_A 覆盖,则无论原始 Key_A 是否关联有超时时间,新的 Key_A 都将继承 Key_B 的所有特性。

请注意,调用 EXPIRE/`PEXPIRE` 时使用非正数超时,或调用 `EXPIREAT`/`PEXPIREAT` 时使用过去的时间,将导致 key 被 删除 而非过期(相应地,发出的 key 事件 将是 del,而不是 expired)。

选项

EXPIRE 命令支持一组选项

  • NX -- 仅当 key 不存在超时时间时才设置超时
  • XX -- 仅当 key 存在超时时间时才设置超时
  • GT -- 仅当新的超时时间大于当前超时时间时才设置
  • LT -- 仅当新的超时时间小于当前超时时间时才设置

对于 GTLT 选项,非易失 key 被视为具有无限 TTL。GTLTNX 选项是互斥的。

刷新超时时间

可以对已经设置了超时时间的 key 调用 EXPIRE 命令。在这种情况下,key 的生存时间会被 更新 为新值。这有很多有用的应用场景,下文的 导航会话 模式章节中记录了一个示例。

Redis 2.1.3 版本之前差异

2.1.3 版本之前的 Redis 中,使用修改 key 值的命令来修改一个已设置超时时间的 key,会导致该 key 被完全移除。这种语义是由于复制层中的限制所必需的,但现在这些限制已得到修复。

EXPIRE 将返回 0,并且不会修改已设置超时时间的 key 的超时时间。

示例

在交互式控制台中尝试这些命令

SET mykey "Hello" EXPIRE mykey 10 TTL mykey SET mykey "Hello World" TTL mykey EXPIRE mykey 10 XX TTL mykey EXPIRE mykey 10 NX TTL mykey

模式:导航会话

假设你有一个 Web 服务,并且你对用户 最近 访问的最新 N 个页面感兴趣,要求每个相邻页面浏览操作与前一个操作之间的时间间隔不超过 60 秒。从概念上讲,你可以将这组页面浏览视为用户的 导航会话,其中可能包含有关他或她当前正在寻找什么类型产品的信息,以便你可以推荐相关产品。

可以使用以下策略在 Redis 中轻松建模此模式:每次用户执行页面浏览时,你都调用以下命令

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

如果用户闲置时间超过 60 秒,则 key 将被删除,之后只有时间间隔小于 60 秒的后续页面浏览才会被记录。

此模式可以轻松修改,以使用 `INCR` 命令的计数器,而不是使用 `RPUSH` 命令的列表。

附录:Redis 过期

带过期时间的 key

通常,创建 Redis key 时不关联生存时间。除非用户通过显式方式移除它,例如使用 `DEL` 命令,否则该 key 将永久存在。

EXPIRE 命令家族能够为给定的 key 关联过期时间,代价是 key 会使用一些额外的内存。当 key 设置了过期时间后,Redis 将确保在指定时间量过后移除该 key。

key 的生存时间可以使用 EXPIRE`PERSIST` 命令(或其它密切相关的命令)进行更新或完全移除。

过期精度

在 Redis 2.4 版本中,过期时间可能不是非常精确,误差在零到一秒之间。

从 Redis 2.6 版本开始,过期误差在 0 到 1 毫秒之间。

过期与持久化

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

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

即使是正在运行的实例,也会始终检查计算机时钟,例如,如果你设置一个生存时间为 1000 秒的 key,然后将计算机时间调到未来 2000 秒,该 key 将立即过期,而不是持续 1000 秒。

Redis 如何使 key 过期

Redis 通过两种方式使 key 过期:被动方式和主动方式。

当客户端尝试访问一个 key 且该 key 已超时时,该 key 会被被动过期。

然而,这还不够,因为有些已过期的 key 可能永远不会再被访问。这些 key 无论如何都应该过期,因此 Redis 会定期从设置了过期时间的 key 集合中随机测试一些 key。所有已经过期的 key 都会从 keyspace 中删除。

为了在不牺牲一致性的情况下获得正确行为,当 key 过期时,会在 AOF 文件中合成一个 `DEL` 操作,并将其传播到所有连接的副本节点。这样,过期过程就集中在主实例上,从而避免了一致性错误的可能性。

然而,虽然连接到主节点的副本不会独立过期 key(而是等待主节点发送的 `DEL` 命令),但它们仍然会获取数据集中存在的完整过期状态,因此当副本被选举为主节点时,它将能够独立过期 key,完全扮演主节点的角色。

RESP2/RESP3 回复

以下之一

  • 整数回复:如果未设置超时时间则返回 0;例如,key 不存在,或者由于提供的参数而跳过了操作。
  • 整数回复:如果已设置超时时间则返回 1

历史

  • 从 Redis 7.0.0 版本开始:添加了选项:NXXXGTLT
为此页面评分
返回顶部 ↑