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 毫秒立即删除、不创建字段。

相关推荐
starzy19904 小时前
Flink 优化之网络缓存优化及参数详解:从数据传输机制到反压原理的生产调优指南
网络·缓存·flink
ShineWinsu5 小时前
对于Redis:string类型的解析
java·c++·redis·分布式·缓存·面试·string
CoLiuRs7 小时前
电商价格是怎样算出来的
数据库·redis·缓存
天衍四九-10 小时前
Docker Compose企业实战系列(四):Redis生产级部署|密码加固、持久化、内存优化完整方案
redis·docker·容器
喜欢的名字被抢了11 小时前
08-Redis 性能优化篇:快在哪、BigKey、HotKey、慢查询与内存
数据库·redis·性能优化
蜗牛互联网12 小时前
HSTU在Dynamo-Triton中的AOTI与KV缓存验收方法
java·人工智能·后端·缓存
青山木12 小时前
秒杀系统设计(一):需求拆解与流量治理
java·数据库·redis·后端·架构
hweiyu001 天前
Redis命令:HMGET
redis·缓存