2026/10/3 2:35:55

Redis命令:HPEXPIREAT

Redis命令:HPEXPIREAT Redis HPEXPIREAT 命令详细教程HPEXPIREAT为 Hash 中一个或多个字段设置绝对到期时刻时间以 Unix 毫秒级时间戳表示。它与 HEXPIREAT 语义相同只是精度为毫秒。资料合集https://pan.quark.cn/s/10e98d308913、https://pan.quark.cn/s/f56bc69c5338一、概览与语法HPEXPIREAT key unix-time-milliseconds [NX | XX | GT | LT] FIELDS numfields field [field ...]项目说明数据类型Hash 的字段级过期时间支持版本Redis 7.4.0 起key一个 Hash Keyunix-time-milliseconds绝对 Unix 时间戳单位毫秒条件选项NX、XX、GT、LT 四者最多选一互斥FIELDS必填关键字numfields字段数量必须与后续字段参数个数一致时间复杂度O(N)N 为指定字段数量ACLwrite、hash、fast命令标记write、denyoom、fast官方明确说明过去的时间戳会立即删除该字段。$TRAE_REF二、逐字段返回值数值含义-2该字段不存在或整个 Key 不存在0指定的 NX、XX、GT、LT 条件未满足1过期时间已设置或更新2传入的是过去的 Unix 时间字段被立即删除官方对2的定义覆盖了四种命令HEXPIRE 或 HPEXPIRE 以 0 秒/毫秒调用HEXPIREAT 或 HPEXPIREAT 以过去的 Unix 时间调用。$TRAE_REF三、基础示例以下命令需要 Redis 7.4 或更新版本在测试实例的 redis-cli 中执行。文中结果是预期说明未实际连接 Redis 运行。官方示例使用的1715704971000是一个毫秒级时间戳。DEL tutorial:{hpexpireat}:profile HSET tutorial:{hpexpireat}:profile field1 hello field2 world HPEXPIREAT tutorial:{hpexpireat}:profile 1715704971000 FIELDS 2 field1 field2 HPTTL tutorial:{hpexpireat}:profile FIELDS 2 field1 field2 HPEXPIRETIME tutorial:{hpexpireat}:profile FIELDS 2 field1 field2 HPEXPIREAT tutorial:{hpexpireat}:profile 1 FIELDS 1 field1 HEXISTS tutorial:{hpexpireat}:profile field1 HEXISTS tutorial:{hpexpireat}:profile field2预期结果HPEXPIREAT 返回[1, 1]HPTTL 返回两个相同的毫秒值官方示例中为 303340 这类数值取决于执行时刻与目标时间戳的差值HPEXPIRETIME 返回两个相同的毫秒时间戳。传入过去的时间戳1后返回[2]field1 被立即删除HEXISTS 返回0而 field2 仍为1。如果示例中的时间戳已经过去第一次调用就会返回[2, 2]并删除两个字段。实际使用时请替换为未来的时间戳。四、如何生成毫秒时间戳毫秒时间戳由客户端生成Redis 不提供换算命令。date%s%3Nimporttimefromdatetimeimportdatetime,timedelta,timezone now_msint(time.time()*1000)print(now_ms)# 当前毫秒时间戳print(now_ms60_000)# 一分钟后print(int((datetime.now(timezone.utc)timedelta(minutes5)).timestamp()*1000))常见错误是把秒级时间戳当作毫秒传入秒级数值比毫秒小三个数量级作为毫秒时间戳几乎必然是“过去的时间”会导致字段被立即删除。反过来把毫秒时间戳传给 HEXPIREAT 则会得到一个极其遥远的未来时刻。换算时务必确认单位。五、条件选项与边界情况选项判断条件NX字段当前没有过期时间时才设置XX字段当前已有过期时间时才设置GT新到期时刻严格晚于当前到期时刻时才设置LT新到期时刻严格早于当前到期时刻时才设置官方说明对于 GT 与 LT没有过期时间的字段被视为无限大的 TTL因此有限时间的 GT 对无 TTL 字段通常不成立LT 会成立。$TRAE_REF场景行为Key 不存在按输入字段数返回多个 -2不创建 Key字段不存在该项返回 -2时间戳已过去该字段被立即删除返回 2时间戳不是整数报参数类型错误Key 是 String、List 等非 Hash报 WRONGTYPE 错误numfields 与实际字段数不符报语法错误六、与相关命令的对照命令对象时间表达单位HPEXPIREHash 字段相对毫秒HPEXPIREATHash 字段绝对毫秒时间戳HEXPIREATHash 字段绝对秒时间戳PEXPIREAT整个 Key绝对毫秒时间戳HPEXPIRETIMEHash 字段查询绝对时刻毫秒时间戳字段级过期与 Key 级过期相互独立谁先到期谁先限制数据可用性。查询字段绝对到期时刻使用 HPEXPIRETIME查询剩余时间使用 HPTTL。七、Python 客户端示例前提为已安装 redis-py 且服务端为 Redis 7.4 或更新版本。importtimeimportredis rredis.Redis(hostlocalhost,port6379,decode_responsesTrue)ktutorial:{hpexpireat}:pythontry:r.delete(k)r.hset(k,mapping{a:A,b:B})fields[a,b,missing]deadline_msint(time.time()*1000)60_000resultr.execute_command(HPEXPIREAT,k,deadline_ms,FIELDS,len(fields),*fields)print(result)# [1, 1, -2]print(r.execute_command(HPEXPIRETIME,k,FIELDS,2,a,b))# [deadline_ms, deadline_ms]print(r.execute_command(HPEXPIREAT,k,1,FIELDS,1,a))# [2]print(r.hexists(k,a))# Falsefinally:r.delete(k)r.close()八、并发、重试与适用场景绝对时间戳的明显优势是重试语义稳定把同一请求原样重发到期时刻不会因为重试时刻变化而延长这一点优于相对 TTL。但重试仍可能重复执行条件选项只按各自规则判断不是通用幂等保证请求超时也不代表未执行应先查询 HPEXPIRETIME 或 HEXISTS 再决定是否重发。单条 HPEXPIREAT 对多个字段原子执行但“先 HSET 写值再 HPEXPIREAT 设期限”是两条独立调用中间可能有其他写入。需要两者一起生效时应使用经过验证的脚本或事务设计。典型场景与外部系统对齐的固定过期时刻、活动截止时间、定时失效的权益字段。由于毫秒时间戳依赖客户端时钟而判定在服务端进行两者存在偏差时实际存活时长会与预期不符跨机房场景应统一时间源并留出余量。九、练习、排错与总结练习新建tutorial:{hpexpireat}:exercise写入 a1、b2用 Python 计算当前时间加 10 分钟的毫秒时间戳执行HPEXPIREAT ... ts FIELDS 2 a b预期返回[1, 1]用 HPEXPIRETIME 确认返回该时间戳再用1无条件调用预期返回[2]且字段被删除。排错要点unknown command 时确认服务端版本不低于 7.4字段被意外立即删除时检查传入的是秒级还是毫秒级时间戳返回 0 检查条件选项返回 -2 检查字段是否缺失HPEXPIRETIME 返回 -1 表示字段永久有效。清理使用DEL tutorial:{hpexpireat}:profile tutorial:{hpexpireat}:exercise。速记7.4 起支持、绝对毫秒时间戳、过去时间戳立即删除、FIELDS 必填、返回 -2/0/1/2、注意单位换算。