Redis命令:HPEXPIRE

Redis HPEXPIRE 命令详细教程

HPEXPIRE 为 Hash 中一个或多个字段设置以毫秒为单位的相对过期时间。它与 HEXPIRE 语义完全相同,区别只在时间精度。

资料合集:https://pan.quark.cn/s/10e98d308913、https://pan.quark.cn/s/f56bc69c5338

一、概览与语法

redis 复制代码
HPEXPIRE key milliseconds [NX | XX | GT | LT] FIELDS numfields field [field ...]
项目 说明
数据类型 Hash 的字段级过期时间
支持版本 Redis 7.4.0 起
key 一个 Hash Key
milliseconds 整数毫秒数,相对于本次命令执行时刻
条件选项 NX、XX、GT、LT 四者最多选一,互斥
FIELDS 必填关键字
numfields 字段数量,必须与后续字段参数个数一致
时间复杂度 O(N),N 为指定字段数量
ACL @write、@hash、@fast
命令标记 write、denyoom、fast

官方描述直接指出:本命令与 HEXPIRE 工作方式相同,只是过期时间以毫秒而非秒指定。$TRAE_REF

二、逐字段返回值

返回数组,元素顺序与输入字段顺序一致。

数值 含义
-2 该字段不存在,或整个 Key 不存在
0 指定的 NX、XX、GT、LT 条件未满足
1 过期时间已设置或更新
2 以 0 毫秒调用时,字段被立即删除

官方说明中,2 的触发条件是:以 0 秒或 0 毫秒调用 HEXPIRE 或 HPEXPIRE,或者以过去的 Unix 时间调用 HEXPIREAT 或 HPEXPIREAT。错误情形包括参数解析失败、缺少必需参数、出现未知参数、参数类型或范围不合法,以及 Key 存在但不是 Hash。$TRAE_REF

三、基础示例

以下命令需要 Redis 7.4 或更新版本,在测试实例的 redis-cli 中执行。文中结果是预期说明,未实际连接 Redis 运行。

redis 复制代码
DEL tutorial:{hpexpire}:profile
HSET tutorial:{hpexpire}:profile name Alice temp draft
HPEXPIRE tutorial:{hpexpire}:profile 2000 FIELDS 2 temp name
HPTTL tutorial:{hpexpire}:profile FIELDS 2 temp name
HPEXPIRE tutorial:{hpexpire}:profile 2000 FIELDS 2 temp absent

预期结果:HPEXPIRE 返回 [1, 1];HPTTL 返回两个接近 2000 的毫秒值;最后一次返回 [1, -2],absent 因不存在为 -2。手动等待超过 2 秒后再执行 HGETALL tutorial:{hpexpire}:profile 会得到空数组,因为两个字段都到期,整个 Key 随之消失。

四、与 HEXPIRE 及绝对时间版本的对照

命令 时间表达 单位 起始版本
HEXPIRE 相对 秒 7.4
HPEXPIRE 相对 毫秒 7.4
HEXPIREAT 绝对 秒级时间戳 7.4
HPEXPIREAT 绝对 毫秒级时间戳 7.4

相对时间适合"从现在起多少时间后过期"的场景,例如缓存 2 秒内有效、验证码 5 分钟有效。绝对时间适合"在某个固定时刻过期"的场景,例如活动在指定时间点结束。相对时间在重试时会重新计时,绝对时间不会,这一点在设计幂等接口时很重要。

毫秒精度并不意味着毫秒级精确定时。Redis 的过期清理是惰性与定期相结合的,字段到期与实际不可见之间可能存在很短但非零的延迟,不要依赖它做精确调度。

五、条件选项 NX、XX、GT、LT

四个选项互斥,对每个字段独立判断。

选项 判断条件
NX 字段当前没有过期时间时才设置
XX 字段当前已有过期时间时才设置
GT 新过期时间严格晚于当前过期时间时才设置
LT 新过期时间严格早于当前过期时间时才设置

官方特别说明:对于 GT 与 LT 而言,没有过期时间的字段(non-volatile)被视为无限大的 TTL。因此有限时间的 GT 对无 TTL 字段通常不成立,而 LT 会成立。$TRAE_REF

redis 复制代码
DEL tutorial:{hpexpire}:cond
HSET tutorial:{hpexpire}:cond a A b B
HPEXPIRE tutorial:{hpexpire}:cond 1000 XX FIELDS 1 a
HPEXPIRE tutorial:{hpexpire}:cond 1000 NX FIELDS 1 a
HPEXPIRE tutorial:{hpexpire}:cond 5000 GT FIELDS 2 a b
HPEXPIRE tutorial:{hpexpire}:cond 100 LT FIELDS 2 a b

在无并发修改的前提下,四次调用依次返回 [0]、[1]、[1, 0]、[1, 1]。GT 对已有 1000 毫秒期限的 a 成立;b 无 TTL 被视为无限远,GT 不成立而 LT 成立。同一调用可能部分字段成功、部分失败。

六、边界情况与错误处理

场景 行为
Key 不存在 按输入字段数返回多个 -2,不创建 Key
字段不存在 该项返回 -2
milliseconds 为 0 该字段被立即删除,返回 2
milliseconds 为负数 报参数范围错误
milliseconds 不是整数 报参数类型错误
Key 是 String、List 等非 Hash 报 WRONGTYPE 错误
numfields 与实际字段数不符 报语法错误

需要注意,HPEXPIRE 只作用于已存在的字段,不会创建字段。若希望写入值的同时设置 TTL,应使用 HSETEX(Redis 8.0 起)。

七、客户端示例

前提为已安装 redis-py 且服务端为 Redis 7.4 或更新版本。使用通用接口显式展示 FIELDS 语法。

python 复制代码
import redis

r = redis.Redis(host="localhost", port=6379, decode_responses=True)
k = "tutorial:{hpexpire}:python"
try:
    r.delete(k)
    r.hset(k, mapping={"a": "A", "b": "B"})

    fields = ["a", "b", "missing"]
    result = r.execute_command("HPEXPIRE", k, 2000, "FIELDS", len(fields), *fields)
    print(result)   # [1, 1, -2]

    print(r.execute_command("HPTTL", k, "FIELDS", 2, "a", "b"))   # 约 [2000, 2000]

    print(r.execute_command("HPEXPIRE", k, 0, "FIELDS", 1, "a"))  # [2],立即删除
    print(r.hexists(k, "a"))   # False
finally:
    r.delete(k)
    r.close()

八、并发、重试与适用场景

单条 HPEXPIRE 对多个字段原子执行,但"先 HSET 写值,再 HPEXPIRE 设期限"是两条独立调用,中间可能有其他写入或客户端中断。需要一起生效时应使用事务或脚本,并检查所有回复。

相对 TTL 的无条件重试会从重试时刻重新计时,可能无意延长有效期。若业务要求固定截止时间,应改用 HPEXPIREAT。请求超时也不代表未执行,重发前可先用 HPTTL 或 HPEXPIRETIME 检查字段当前状态。

典型场景:需要亚秒级精度的短缓存字段、限流窗口、短时令牌。控制每批字段数量与 Hash 规模,不要把过期机制当作精确任务调度器。

九、练习、排错与总结

练习:新建 tutorial:{hpexpire}:exercise,写入 a=1、b=2;执行 HPEXPIRE ... 1500 FIELDS 2 a b,预期返回 [1, 1];用 HPTTL 确认两个字段都有接近 1500 的毫秒值;等待超过 1.5 秒后执行 HLEN,预期返回 0,因为两个字段都已到期、Key 随之消失。

排错要点:unknown command 时确认服务端版本不低于 7.4;返回 0 检查条件选项;返回 -2 检查字段是否缺失或已到期;返回 2 说明传入了 0 或已过去的时间;HPTTL 返回 -1 表示字段永久有效而非命令失败。清理使用 DEL tutorial:{hpexpire}:profile tutorial:{hpexpire}:cond tutorial:{hpexpire}:exercise。速记:7.4 起支持、毫秒相对时间、FIELDS 必填、返回 -2/0/1/2、0 毫秒立即删除、不创建字段。

相关推荐
码士集团小青7 小时前
SpringBoot 集成缓存性能之王 Caffeine
spring boot·后端·缓存
SHENGWEI胜为11 小时前
交换机端口显示正常,终端却获取不到 IP 地址?从 DHCP 流程定位故障
服务器·网络·测试工具·缓存·通信工程
夕除14 小时前
redis--数据类型 string list
redis
一条泥憨鱼14 小时前
【Redis | 黑马点评】分布式锁;Lua脚本;Redisson与看门狗 |源码万字详解
redis·分布式·lua
stark张宇15 小时前
库存扣减的“锁”事:悲观锁、乐观锁、分布式锁
redis·分布式·mysql
AAASilverwolf16 小时前
OpenAI 新增 12 小时提示缓存:跨小时任务能省多少?
人工智能·gpt·缓存·api
Sayuanni%319 小时前
Redis(初阶)
数据库·redis·缓存
未秃头的程序猿20 小时前
一次重复扣款的复盘:分布式锁加错了维度,比不加锁更危险
java·redis·后端
XiYang-DING20 小时前
P5528.带过期时间的 LRU 缓存
java·开发语言·缓存
2301_777998341 天前
ARP协议进阶:ARP缓存、RARP与ARP欺骗原理解析
linux·服务器·网络·网络协议·缓存