Redis命令:HPTTL

Redis HPTTL 命令详细教程

HPTTL 查询 Hash 中一个或多个字段的剩余生存时间,以毫秒为单位返回。它是只读命令,不修改任何数据或期限。

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

一、概览与语法

redis 复制代码
HPTTL key FIELDS numfields field [field ...]
项目 说明
数据类型 Hash 的字段级过期时间
支持版本 Redis 7.4.0 起
key 一个 Hash Key
FIELDS 必填关键字,不可省略
numfields 字段数量,必须与后续字段参数个数一致
field 至少一个字段名;不支持通配符
返回值 数组,元素顺序与输入字段顺序一致
时间复杂度 O(N),N 为指定字段数量
ACL @read、@hash、@fast
命令标记 readonly、fast

官方说明:与 HTTL 相同,返回设置了过期时间的字段的剩余 TTL,但单位是毫秒而非秒。$TRAE_REF

二、返回值含义

数值 含义
-2 该字段不存在,或整个 Key 不存在
-1 该字段存在,但没有设置过期时间(永久字段)
非负整数 剩余生存时间,单位毫秒

官方示例清楚展示了三种结果的并存:对 field1 设置了 300 秒 TTL,field2 无 TTL,field3 不存在,查询返回 292202、-1、-2 三个值。$TRAE_REF

-1 与 -2 的区别是关键:-1 表示字段永久有效,-2 表示字段根本不存在。把两者混为一谈会导致"把永久字段当成缺失字段重新写入"这类逻辑错误。

三、基础示例

以下命令需要 Redis 7.4 或更新版本,在测试实例的 redis-cli 中执行。文中结果是预期说明,未实际连接 Redis 运行。官方示例还演示了不存在的 Key 的返回形态。

redis 复制代码
HPTTL tutorial:{hpttl}:missing FIELDS 3 field1 field2 field3
DEL tutorial:{hpttl}:mykey
HSET tutorial:{hpttl}:mykey field1 hello field2 world
HEXPIRE tutorial:{hpttl}:mykey 300 FIELDS 2 field1 field3
HPTTL tutorial:{hpttl}:mykey FIELDS 3 field1 field2 field3

预期结果:第一条对不存在的 Key 返回 (nil)(即空值,而非数组)。HEXPIRE 返回 [1, -2],field1 设置成功,field3 因不存在返回 -2。最后一条返回形如 [292202, -1, -2]:field1 是毫秒剩余时间,field2 无 TTL,field3 不存在。

注意 Key 不存在时的返回与字段不存在时不同:整个 Key 缺失时返回空值,Key 存在但字段缺失时返回数组中对应位置的 -2。这一点与 HTTL 一致,容易在客户端处理时被忽略。

四、HTTL 与 HPTTL 的对照

命令 单位 返回剩余时间 适用场景
HTTL 秒 是 人工排查、秒级精度足够
HPTTL 毫秒 是 亚秒级 TTL、精度核对
HEXPIRETIME 秒 否,返回绝对时刻 需要知道具体到期时间点
HPEXPIRETIME 毫秒 否,返回绝对时刻 毫秒级绝对到期时刻

HPTTL 的数值随时间递减,每次调用都可能得到不同结果;HPEXPIRETIME 在期限内保持稳定。需要判断"还能活多久"用 HPTTL,需要判断"什么时候到期"用 HPEXPIRETIME。

五、字段 TTL 与 Key TTL 的区别

HPTTL 只查询字段级 TTL,与整个 Key 的 TTL 是两套独立机制。

命令 作用对象 单位
TTL / PTTL 整个 Key 秒 / 毫秒
HTTL / HPTTL Hash 字段 秒 / 毫秒
redis 复制代码
DEL tutorial:{hpttl}:two
HSET tutorial:{hpttl}:two a 1
EXPIRE tutorial:{hpttl}:two 600
HPEXPIRE tutorial:{hpttl}:two 300000 FIELDS 1 a
TTL tutorial:{hpttl}:two
HPTTL tutorial:{hpttl}:two FIELDS 1 a

预期结果:TTL 约为 600,HPTTL 约为 300000,两者独立存在,谁先到期谁先限制数据可用性。要让字段永久有效使用 HPERSIST,要让整个 Key 永久有效使用 PERSIST。

六、边界情况与错误处理

场景 行为
Key 不存在 返回空值(Nil),不是数组
字段不存在 该项返回 -2
字段无 TTL 该项返回 -1
字段有 TTL 该项返回毫秒剩余时间,随时间递减
Key 是 String、List 等非 Hash 报 WRONGTYPE 错误
numfields 与实际字段数不符 报语法错误
未写 FIELDS 关键字 报语法错误

HPTTL 不会刷新字段或 Key 的 TTL。读取本身不影响生命周期,这与访问时间(LRU)统计是两回事。

七、Python 客户端示例

前提为已安装 redis-py 且服务端为 Redis 7.4 或更新版本。

python 复制代码
import redis

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

    fields = ["a", "b", "missing"]
    raw = r.execute_command("HPTTL", k, "FIELDS", len(fields), *fields)
    print(raw)   # 形如 [299847, -1, -2]

    for name, value in zip(fields, raw):
        if value == -2:
            print(name, "不存在")
        elif value == -1:
            print(name, "永久有效")
        else:
            print(name, "剩余毫秒", value)

    print(r.execute_command("HPTTL", "tutorial:{hpttl}:missing", "FIELDS", 1, "a"))
    # None,整个 Key 不存在时返回空值
finally:
    r.delete(k)
    r.close()

八、并发、原子性与典型场景

单条 HPTTL 是原子的,返回执行瞬间的快照。但"先 HPTTL 判断是否临近过期,再决定续期"是跨命令流程,两次调用之间字段可能已到期或被其他客户端续期。需要原子条件续期时,可使用 HGETEX(Redis 8.0 起)或 Lua 脚本。

典型用途:监控字段剩余寿命、核对续期逻辑是否符合预期、在业务中判断"即将过期则主动刷新"、排查字段为何提前消失。由于是只读且复杂度只与查询字段数相关,可以安全地用于线上排障。

九、练习、排错与总结

练习:新建 tutorial:{hpttl}:exercise,写入 a=1、b=2;查询两个字段,预期 [-1, -1];用 HPEXPIRE ... 300000 FIELDS 1 a 设置 TTL 后再次查询,预期 a 为接近 300000 的毫秒值、b 为 -1;执行 HPERSIST ... FIELDS 1 a 后查询,预期 a 回到 -1;最后查询一个不存在的字段名,预期为 -2。

排错要点:返回 -1 表示字段永久有效而非缺失;返回 -2 表示字段或 Key 不存在;整个 Key 缺失时返回空值而非数组,客户端需单独处理;数值只有三位数说明用的是秒级 HTTL,应确认命令选择;unknown command 时检查服务端版本不低于 7.4。清理使用 DEL tutorial:{hpttl}:missing tutorial:{hpttl}:mykey tutorial:{hpttl}:two tutorial:{hpttl}:exercise。速记:7.4 起支持、只读、毫秒剩余时间、FIELDS 必填、-1 永久、-2 不存在、Key 缺失返回空值。

相关推荐
imDwAaY1 小时前
Redis List 是链表吗?从 Ziplist 到 Quicklist 揭开底层实现
redis·后端
知守观2 小时前
从三个带病的 Guava 本地缓存出发:Redis + Guava 二级缓存的读写路径与失效设计推演
java·redis·后端
imDwAaY2 小时前
Redis Set 如何节省内存?从整数集合到哈希表的设计取舍
数据结构·redis·散列表
ly76892 小时前
Spring Boot 集成 Redis 企业级实践:连接池、序列化与缓存穿透雪崩的工程化防御
spring boot·redis·缓存·缓存穿透·布隆过滤器·lettuce 连接池
x-Achan3 小时前
Redis实现方案:更新策略、穿透、雪崩、击穿、工具封装
java·spring boot·redis·spring·bootstrap·mybatis
ShineWinsu1 天前
对于Redis:Hash类型的解析
c++·redis·分布式·缓存·面试·hash·哈希表
.Hypocritical.1 天前
Redis从入门到实战:核心原理、场景落地与避坑指南
数据库·redis·缓存
用户6222884048191 天前
Redis 分布式锁:从 2.8 之前到 2.8+,一篇讲透
redis