首页/数据/数据库速查/EXPIRE 条件选项 NX/XX/GT/LT(7.0)
Redis 命令96 条

EXPIRE 条件选项 NX/XX/GT/LT(7.0)

EXPIRE 支持 NX/XX/GT/LT 条件设置与 EXPIRETIME/PEXPIRETIME 读取绝对过期时间:刷新 TTL 时不再盲目覆盖,避免把长 TTL 改短或反之。

数据库速查数据更新于 2026-10-13

EXPIRE 条件选项是什么

从 7.0 起,EXPIRE 支持 NX、XX、GT、LT 四个条件选项,用来控制「什么情况下才更新 TTL」。它解决的是多套逻辑互相覆盖过期时间的经典问题:缓存预热想把 TTL 设长、降级逻辑想把 TTL 设短,两者互不知情地刷新同一个键,结果 TTL 忽长忽短。同时 7.0 新增 EXPIRETIME 与 PEXPIRETIME,可以直接读出绝对过期时间戳,而不是只能用 TTL 反推。

基本信息

NX仅当键没有 TTL 时设置
XX仅当键已有 TTL 时更新
GT仅当新 TTL 大于当前 TTL 时更新;永久键视为无限大,永不满足
LT仅当新 TTL 小于当前 TTL 时更新;永久键视为无限大,总满足
读取绝对时间EXPIRETIME 返回秒级时间戳,PEXPIRETIME 返回毫秒级(7.0+)

典型使用场景

  • 长 TTL 优先:缓存预热与业务读取都要刷新 TTL 时,用 GT 保证短 TTL 不会覆盖长 TTL
  • 临时降级不拉长:故障降级期间把 TTL 压短,用 LT 避免被其他逻辑又刷长
  • 首次写入才设过期:用 NX 避免把已经设过 TTL 的键重新设定
  • 只续期已有缓存:用 XX 避免给不存在的键写入 TTL 造成空键
  • 过期时间审计:用 EXPIRETIME 直接取绝对时间点,便于与业务日志对齐

条件刷新示例

条件刷新示例
SET k v
EXPIRE k 60 NX        # 仅当还没有 TTL 时设置
EXPIRE k 120 XX       # 仅当已有 TTL 时更新
EXPIRE k 30 GT        # 仅当新 TTL 更大才更新(永久键不生效)
EXPIRE k 30 LT        # 仅当新 TTL 更小才更新(永久键会生效)
TTL k                 # 剩余秒数
EXPIRETIME k          # 绝对过期时间(秒级时间戳,7.0+)
PEXPIRETIME k         # 毫秒级绝对时间
PERSIST k             # 去掉 TTL,把键变回永久

四个选项的边界行为

选项键无 TTL 时键有 TTL 时典型用途
NX设置成功不生效首次写入才设过期
XX不生效设置成功只续期已有的键
GT不生效(视为无限大)新值更大才生效长 TTL 优先
LT生效(视为无限大)新值更小才生效临时降级压短 TTL
GT 与 LT 的语义边界容易记反:永久键没有 TTL,被视为『无限大』,所以 GT 永远不满足、LT 永远满足。改动过期逻辑前先用这两个边界用例自测。
7.0 之前传入 NX/GT 会直接语法报错。客户端库与中间件(如代理层)可能对命令做兼容改写,升级前确认链路各环节支持的命令版本。

易错点

  • 以为对永久键用 GT 能把 TTL 设上:永久键被视为无限大,GT 一定不满足,命令返回 0 但键仍无过期时间
  • 把 GT/LT 与「大于等于 / 小于等于」混淆:它们是严格比较,修改续期逻辑前要按边界用例验证
  • 在老版本实例上使用这些选项:直接报语法错误,客户端报错信息可能被包装成通用命令失败,排查时先核对服务端版本
  • 用 TTL 反推绝对过期时间:TTL 是相对值且随读取时刻变化,需要绝对时间点时应使用 EXPIRETIME
  • 多套逻辑同时刷新 TTL 却不约好条件选项:TTL 被互相覆盖,表现为缓存时而过期过早、时而长期不淘汰

数据来源与参考

  • Redis 官方文档: EXPIRE
  • Redis 官方文档: EXPIRETIME

相关工具

​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌