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 区分。