Redis命令:HSTRLEN

Redis HSTRLEN 命令详细教程

HSTRLEN 返回 Hash 中指定字段值的字符串长度,单位是字节。它从 Redis 3.2.0 起提供,时间复杂度 O(1),不需要传输字段值本身。

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

一、概览与语法

redis 复制代码
HSTRLEN key field
项目 说明
数据类型 Hash
支持版本 Redis 3.2.0 起
key Hash 的 Key
field 一个字段名,不支持通配符
返回值 整数,字段值的字节长度;字段或 Key 不存在时返回 0
时间复杂度 O(1)
ACL @read、@hash、@fast
命令标记 readonly、fast

官方说明:返回字段值的字符串长度;如果 Key 或字段不存在,返回 0。$TRAE_REF

二、基础示例

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

redis 复制代码
DEL tutorial:{hstrlen}:myhash
HSET tutorial:{hstrlen}:myhash f1 HelloWorld f2 99 f3 -256
HSTRLEN tutorial:{hstrlen}:myhash f1
HSTRLEN tutorial:{hstrlen}:myhash f2
HSTRLEN tutorial:{hstrlen}:myhash f3
HSTRLEN tutorial:{hstrlen}:myhash absent
HSTRLEN tutorial:{hstrlen}:missing f1

预期结果:HSET 返回 3;HSTRLEN 对 f1 返回 10,对 f2 返回 2,对 f3 返回 4(含负号)。对不存在的字段返回 0,对不存在的 Key 也返回 0。

注意 "99" 的长度是 2,"-256" 的长度是 4。HSTRLEN 统计的是字符个数(按字节),不是数值大小。

三、长度单位是字节,不是字符

Redis 字符串是二进制安全的,长度按字节计算。对于 ASCII 文本,字节数等于字符数;对于中文等多字节字符,一个汉字在 UTF-8 下占 3 个字节。

值 HSTRLEN 说明
"abc" 3 ASCII,1 字节 1 字符
"你好" 6 UTF-8 下每个汉字 3 字节
"é" 2 UTF-8 下为 2 字节
"99" 2 数字文本同样按字符计
"" 0 空字符串长度为 0
redis 复制代码
DEL tutorial:{hstrlen}:text
HSET tutorial:{hstrlen}:text en abc zh 你好 empty ""
HSTRLEN tutorial:{hstrlen}:text en
HSTRLEN tutorial:{hstrlen}:text zh
HSTRLEN tutorial:{hstrlen}:text empty

预期结果:en 返回 3,zh 返回 6,empty 返回 0。

空字符串长度为 0,与"字段不存在返回 0"结果相同,这是本命令最需要注意的地方:单看返回值无法区分"字段存在但内容为空"和"字段不存在"。需要区分时配合 HEXISTS:

状态 HSTRLEN HEXISTS HGET
字段不存在 0 0 空值
字段存在,值为 "" 0 1 空字符串
字段存在,值为 "abc" 3 1 "abc"

四、与相近命令的区别

命令 作用对象 返回内容 复杂度
HSTRLEN Hash 字段值 字节长度 O(1)
STRLEN String Key 字节长度 O(1)
HLEN Hash 字段数量 O(1)
HGET Hash 字段 值本身 O(1)
HEXISTS Hash 字段 是否存在 O(1)

HSTRLEN 与 STRLEN 容易混淆:前者作用于 Hash 的某个字段,后者作用于 String 类型的整个 Key。HSTRLEN 与 HLEN 也容易混淆:前者是"某个值的长度",后者是"字段的个数"。

五、错误与边界情况

场景 行为
Key 不存在 返回 0
字段不存在 返回 0
字段值为空字符串 返回 0,与字段不存在结果相同
Key 是 String、List 等非 Hash 报 WRONGTYPE 错误
参数个数不对 报语法错误,HSTRLEN 只接受 key 与 field
字段名大小写不同 视为不同字段
redis 复制代码
SET tutorial:{hstrlen}:wrong text
HSTRLEN tutorial:{hstrlen}:wrong f1

上述命令会报 WRONGTYPE,而不是返回 0。需要注意:类型错误是异常,字段不存在是正常返回 0,两者不应混为一谈。

六、典型场景与性能

HSTRLEN 的核心价值在于"只取长度,不取内容"。当字段值很大而业务只关心大小时,它能避免把整个值传输到客户端,节省带宽与客户端内存。

场景 说明
校验写入长度 写入后确认是否超过限制
监控值膨胀 定期检查大字段的长度变化
估算内存占用 结合字段数量评估 Hash 规模
判断是否为空 配合 HEXISTS 区分空值与缺失
避免传输大值 只关心长度时不必 HGET 全量

复杂度为 O(1),因为 Redis 内部记录了字符串长度,无需遍历内容。它是 @fast 命令,可以安全地用于线上高频调用。

七、客户端示例

前提为已安装 redis-py 并准备好本地测试实例。

python 复制代码
import redis

r = redis.Redis(host="localhost", port=6379, decode_responses=True)
k = "tutorial:{hstrlen}:python"
try:
    r.delete(k)
    r.hset(k, mapping={"en": "abc", "zh": "你好", "empty": ""})

    print(r.hstrlen(k, "en"))       # 3
    print(r.hstrlen(k, "zh"))       # 6,UTF-8 每个汉字 3 字节
    print(r.hstrlen(k, "empty"))    # 0
    print(r.hstrlen(k, "absent"))   # 0

    # 区分空值与缺失
    for name in ("empty", "absent"):
        print(name, r.hstrlen(k, name), r.hexists(k, name))
    # empty 0 True
    # absent 0 False
finally:
    r.delete(k)
    r.close()

Java(Jedis)示例:

java 复制代码
try (Jedis jedis = new Jedis("localhost", 6379)) {
    jedis.hset("tutorial:{hstrlen}:java", "f1", "HelloWorld");
    System.out.println(jedis.hstrlen("tutorial:{hstrlen}:java", "f1"));       // 10
    System.out.println(jedis.hstrlen("tutorial:{hstrlen}:java", "absent"));   // 0
    jedis.del("tutorial:{hstrlen}:java");
}

八、TTL 与并发说明

HSTRLEN 是只读命令,不会刷新字段或 Key 的 TTL。在 Redis 7.4 及以后,字段可以单独设置过期时间;字段到期后 HSTRLEN 返回 0,与字段从未存在表现一致,需要区分时可配合 HTTL 或 HEXISTS。

单条 HSTRLEN 是原子的,返回执行瞬间的长度快照。但"先 HSTRLEN 判断长度,再决定是否写入"是跨命令流程,两次调用之间其他客户端可能已修改该字段。需要严格限制长度时,应在 Lua 脚本中完成判断与写入。

九、练习、排错与总结

练习:新建 tutorial:{hstrlen}:exercise,写入 ascii=hello、cjk=你好世界、empty="";分别执行 HSTRLEN,预期为 5、12、0;查询不存在的字段,预期为 0;用 HEXISTS 区分 empty 与不存在的字段,确认两者 HEXISTS 分别为 1 和 0。

排错要点:返回 0 时用 HEXISTS 区分空字符串与字段缺失;中文长度大于预期说明按字节计算,业务需要字符数时应自行按 UTF-8 解码后计数;报 WRONGTYPE 时用 TYPE 检查类型;长度与 HLEN 混淆时注意前者是值长度、后者是字段个数;unknown command 时确认服务端版本不低于 3.2。清理使用 DEL tutorial:{hstrlen}:myhash tutorial:{hstrlen}:text tutorial:{hstrlen}:wrong tutorial:{hstrlen}:exercise。速记:3.2 起支持、O(1) 只返回长度、单位是字节、缺失与空值都返回 0、需配合 HEXISTS 区分。

相关推荐
字节渡客3 小时前
Redis键明明过期了,业务还在读到旧数据
数据库·redis·spring
前端兰博4 小时前
05-Redis
redis·后端
OnlineProxy5 小时前
亚马逊多账号运营:如何在规避“关联封号”风险的同时实现电商规模化扩张
服务器·数据库·redis
ShineWinsu10 小时前
对于Redis:主从复制的解析
linux·数据库·c++·redis·缓存·面试·主从复制
ShineWinsu13 小时前
对于Redis:事务的解析
数据库·redis·mysql·缓存·面试·事务·acid
JavaPub-rodert14 小时前
公共 Docker 镜像源总失效?用 Harbor Proxy Cache 自建 Docker Hub 镜像缓存
java·缓存·docker
夕除15 小时前
redis--OpenResty
java·redis
hweiyu0017 小时前
Redis命令:HRANDFIELD
redis·缓存
jyOverQ17 小时前
Redis 持久化怎么做?RDB、AOF 与混合持久化
数据库·redis