Redis命令:HPERSIST

Redis HPERSIST 命令详细教程

HPERSIST 移除 Hash 中一个或多个字段的过期时间,把字段从"易失"变为"永久"。它从 Redis 7.4.0 起提供,只读不写数据本身,只改动过期元数据。

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

一、概览与语法

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

命令描述中给出了术语定义:带有过期时间的字段称为 volatile(易失),移除后成为 persistent(永久,不再关联 TTL)。$TRAE_REF

二、逐字段返回值

数值 含义
-2 该字段不存在,或整个 Key 不存在
-1 该字段存在,但本来就没有过期时间
1 成功移除了该字段的过期时间

即使只指定一个字段也返回数组,不能当成单个整数处理。-1 与 -2 的区别很关键:前者表示字段存在且已是永久状态(操作无效果但数据正常),后者表示字段根本不存在。$TRAE_REF

三、基础示例

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

redis 复制代码
DEL tutorial:{hpersist}:profile
HSET tutorial:{hpersist}:profile name Alice temp draft
HEXPIRE tutorial:{hpersist}:profile 300 FIELDS 2 name temp
HTTL tutorial:{hpersist}:profile FIELDS 2 name temp
HPERSIST tutorial:{hpersist}:profile FIELDS 1 temp
HTTL tutorial:{hpersist}:profile FIELDS 2 name temp
HPERSIST tutorial:{hpersist}:profile FIELDS 2 name absent

预期结果:HEXPIRE 返回 [1, 1];第一次 HTTL 返回两个递减的正数;HPERSIST 对 temp 返回 [1];第二次 HTTL 中 temp 变为 -1,name 仍为正数;最后一次 HPERSIST 返回 [1, -2],name 被成功转为永久,absent 因不存在返回 -2。

四、字段 TTL 与 Key TTL 的区别

这是最容易混淆的地方。HPERSIST 只作用于字段级过期时间,不影响整个 Key 的过期时间。

操作对象 设置命令 查询命令 移除命令
Hash 字段 HEXPIRE、HPEXPIRE、HEXPIREAT、HPEXPIREAT HTTL、HPTTL、HEXPIRETIME、HPEXPIRETIME HPERSIST
整个 Key EXPIRE、PEXPIRE、EXPIREAT、PEXPIREAT TTL、PTTL、EXPIRETIME、PEXPIRETIME PERSIST
redis 复制代码
DEL tutorial:{hpersist}:two
HSET tutorial:{hpersist}:two a 1
EXPIRE tutorial:{hpersist}:two 600
HEXPIRE tutorial:{hpersist}:two 300 FIELDS 1 a
TTL tutorial:{hpersist}:two
HTTL tutorial:{hpersist}:two FIELDS 1 a
HPERSIST tutorial:{hpersist}:two FIELDS 1 a
TTL tutorial:{hpersist}:two
HTTL tutorial:{hpersist}:two FIELDS 1 a

预期结果:TTL 约为 600,HTTL 约为 300,两者独立存在;HPERSIST 后 HTTL 变为 -1,但 TTL 仍约为 600,说明 Key 级过期时间未受影响。要让整个 Key 永久有效,应使用 PERSIST。

五、边界情况与错误处理

场景 行为
Key 不存在 按输入字段数返回多个 -2
字段不存在 该项返回 -2
字段存在但无 TTL 该项返回 -1,属于"无需操作"而非失败
字段有 TTL 该项返回 1,TTL 被移除,值保持不变
Key 是 String、List 等非 Hash 报 WRONGTYPE 错误
numfields 与实际字段数不符 报语法错误
未写 FIELDS 关键字 报语法错误

HPERSIST 不会改变字段的值,也不会改变 Key 的 TTL。若字段已经到期,它的表现与不存在一致,返回 -2,无法"复活"已删除的数据。

六、客户端示例

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

python 复制代码
import redis

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

    fields = ["a", "absent"]
    result = r.execute_command("HPERSIST", k, "FIELDS", len(fields), *fields)
    print(result)   # [1, -2]

    for name, value in zip(fields, result):
        if value == 1:
            print(name, "已转为永久")
        elif value == -1:
            print(name, "本来就是永久")
        else:
            print(name, "不存在")

    print(r.execute_command("HTTL", k, "FIELDS", 2, "a", "b"))   # [-1, 约300]
finally:
    r.delete(k)
    r.close()

七、并发、原子性与适用场景

HPERSIST 对多个字段原子执行,但"先 HTTL 判断,再 HPERSIST"是跨命令流程,中间可能有其他客户端重新设置 TTL 或删除字段。需要严格条件操作时应使用脚本或事务设计。

典型场景:把原本设了短 TTL 的字段在满足某条件后转为长期有效(例如支付完成后把订单缓存字段转永久)、修正误设的过期时间、在数据迁移前冻结字段生命周期。需要注意的是,转为永久意味着该字段将一直占用内存,直到被显式删除或整个 Key 消失;把大量字段转为永久会削弱缓存自动清理的效果,应配合容量规划。

八、练习、排错与总结

练习:新建 tutorial:{hpersist}:exercise,写入 a=1、b=2;用 HEXPIRE ... 300 FIELDS 2 a b 设置字段 TTL;执行 HPERSIST ... FIELDS 2 a absent,预期返回 [1, -2];用 HTTL 确认 a 为 -1、b 仍为正数;最后执行 PERSIST 观察 Key 级 TTL 的变化,理解两级过期的独立性。

排错要点:返回 -1 表示字段本来就永久,不是失败;返回 -2 表示字段或 Key 不存在,可用 HEXISTS 与 EXISTS 区分;unknown command 时确认服务端版本不低于 7.4;HTTL 仍有数值说明命令未作用到该字段,检查字段名拼写与 numfields 是否匹配。清理使用 DEL tutorial:{hpersist}:profile tutorial:{hpersist}:two tutorial:{hpersist}:exercise。速记:7.4 起支持、移除字段 TTL 而非 Key TTL、返回 -2/-1/1、不改变字段值、大量转永久需评估内存。

相关推荐
码哥字节7 小时前
缓存一致性:先删缓存还是先更新库?3 种方案对比 + 实战
redis
2501_933923258 小时前
解读Redis:单线程模型
数据库·redis·缓存
我不会起名字3228 小时前
seq 空洞排查:Mongo 的 51 只是预留上界,Redis CURR 才是已消耗边界
redis·后端·mongodb·go·即时通讯·im·故障排查
时间的拾荒人12 小时前
Redis 集合类型详解:Set 与 Zset
redis·缓存·面试
鶴哥只手遮天14 小时前
《Redis 8.10.3 深度剖析》系列 ·第 17 章. 一个迟到十六年的类型
redis·后端·开源
IT规划师16 小时前
Redis 数据类型全解 - 数据类型选型矩阵:一张表、一棵树、四条线(十二)
redis·数据类型
虹科网络安全1 天前
Redis Radar:在统一视图中掌握 Redis 部署、健康与容量
经验分享·redis·艾体宝·艾体宝it·艾体宝redis
大大大大晴天1 天前
每天认识一个组件:Redis
redis