☰
Redis命令:HGETALL
2026/9/26 16:29:18 网站建设 项目流程

Redis HGETALL 命令详细教程

HGETALL返回 Hash 中全部字段与值。回复长度是 Hash 大小的两倍,字段顺序不保证稳定。

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

一、概览与语法

HGETALL key
项目说明
数据类型Hash
支持版本Redis 2.0.0 起
key一个 Hash Key
返回值RESP2 为字段与值交替出现的数组;RESP3 为映射
空结果Key 不存在时返回空数组(RESP3 为空映射),不是 Null
时间复杂度O(N),N 为 Hash 大小
ACL@read、@hash、@slow
命令标记readonly

官方明确标注该命令的输出顺序不确定(nondeterministic output order),且被归类为@slow,因为耗时随 Hash 大小线性增长。$TRAE_REF

二、基础示例

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

DEL tutorial:{hgetall}:user tutorial:{hgetall}:missing HSET tutorial:{hgetall}:user name Alice city Shanghai age 30 HGETALL tutorial:{hgetall}:user HLEN tutorial:{hgetall}:user HGETALL tutorial:{hgetall}:missing EXISTS tutorial:{hgetall}:missing

预期结果:HGETALL 返回 6 个元素的数组,形如"name" "Alice" "city" "Shanghai" "age" "30",但实际排列顺序可能不同;HLEN 返回3;对缺失 Key 调用返回空数组且不创建 Key,EXISTS 为0。

注意返回的是“字段名、值”交替的扁平数组,不是嵌套结构。字段数量等于回复长度的一半,可用这一点做校验。

三、输出顺序与解析

Redis 不承诺 HGETALL 的字段顺序,小型 Hash 常表现为插入顺序或内部编码顺序,但这是实现细节,不能作为业务依据。需要固定顺序时应在客户端对结果排序,或改用 SORT 等显式排序手段。

RESP2 与 RESP3 的形态差异会影响客户端解码:

协议形态典型客户端表现
RESP2字段与值交替的数组列表、字符串数组、部分客户端已转换为字典
RESP3映射(Map)直接是字典、Map 或对象

redis-py 在 RESP2 下也会把 HGETALL 解码为字典,但这属于客户端行为,不代表服务端返回了映射结构。自行解析原始协议时应按“偶数下标为字段、奇数下标为值”处理,并校验长度为偶数。

pairs=["name","Alice","age","30"]result={pairs[i]:pairs[i+1]foriinrange(0,len(pairs),2)}print(result)# {'name': 'Alice', 'age': '30'}

四、空 Hash、缺失 Key 与错误类型

场景行为
Key 不存在返回空数组或空映射,不报错,不创建 Key
Key 已到期视作不存在,返回空结果
Hash 存在但字段全部到期或被删除由于最后一个字段消失时 Key 被删除,通常表现为 Key 不存在
Key 是 String、List 等非 Hash报 WRONGTYPE 错误
字段值为空字符串正常返回该字段,值为空字符串
字段名重复不可能出现,Hash 字段名唯一
DEL tutorial:{hgetall}:empty HSET tutorial:{hgetall}:empty a "" HGETALL tutorial:{hgetall}:empty SET tutorial:{hgetall}:wrong text HGETALL tutorial:{hgetall}:wrong

第二次调用返回"a"与空字符串两项,说明值为空字符串的字段同样会被列出。最后一条命令报 WRONGTYPE。

五、大 Hash 的性能风险

HGETALL 的时间复杂度是 O(N),并且会把整个 Hash 一次性传输到客户端。字段很多或值很大时,会造成明显的服务端阻塞风险、网络带宽占用和客户端内存压力。官方将其标记为@slow正是基于这一点。

场景建议方式
只需要几个已知字段HMGET,或用多条 HGET
只关心字段名或值HKEYS、HVALS
需要遍历大 HashHSCAN 增量游标遍历
需要统计字段数量HLEN
需要单个字段长度HSTRLEN
确实需要全部数据HGETALL,但先评估规模并考虑分批

在线上排查“某个 Hash 到底有多大”时,优先使用 HLEN,而不是直接 HGETALL。必要时可在从库或离线实例上执行完整读取。

六、客户端示例

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

importredis r=redis.Redis(host="localhost",port=6379,decode_responses=True)k="tutorial:{hgetall}:python"try:r.delete(k)r.hset(k,mapping={"name":"Alice","age":"30","empty":""})data=r.hgetall(k)print(data)# {'name': 'Alice', 'age': '30', 'empty': ''}print(len(data))# 3print(data.get("absent"))# Noneprint(r.hgetall("tutorial:{hgetall}:missing"))# {}finally:r.delete(k)r.close()

Java(Jedis)示例,返回 Map:

try(Jedisjedis=newJedis("localhost",6379)){jedis.hset("tutorial:{hgetall}:java","name","Alice");jedis.hset("tutorial:{hgetall}:java","age","30");Map<String,String>all=jedis.hgetAll("tutorial:{hgetall}:java");System.out.println(all);jedis.del("tutorial:{hgetall}:java");}

七、原子性、一致性与常见用途

单条 HGETALL 是原子的,返回的是执行瞬间的一致快照,不会读到“写了一半”的 Hash。但如果先 HGETALL 再写回,两次调用之间其他客户端可能已经修改数据,这种“读改写”流程不具备原子性,应按需求使用 WATCH 事务或 Lua 脚本。

典型用途:读取小对象的所有属性、把 Hash 当作对象存储后整体加载、配置项一次性取出、缓存预热。不要把它当作全量扫描工具用于大 Key,也不要在高频接口中对大 Hash 反复调用。

八、练习、排错与总结

练习:新建tutorial:{hgetall}:exercise,写入 a=1、b=2、c=3;执行 HGETALL 并确认返回 6 个元素;用 HLEN 确认字段数为 3;执行HDEL ... a b c后再次 HGETALL,预期得到空数组且 EXISTS 为 0,说明最后一个字段被删除时整个 Key 一并消失。

排错要点:返回空结果时先用 EXISTS 区分 Key 缺失与 Hash 为空;报 WRONGTYPE 时用 TYPE 检查类型;结果顺序与预期不同属正常现象,不应依赖顺序;客户端拿到的字段数少于预期时检查是否有字段已到期;出现明显延迟时评估 Hash 规模并改用 HSCAN。清理使用DEL tutorial:{hgetall}:user tutorial:{hgetall}:missing tutorial:{hgetall}:empty tutorial:{hgetall}:wrong tutorial:{hgetall}:exercise。速记:读取全部字段与值、O(N) 且标记为慢命令、顺序不保证、缺失 Key 返回空结果而非 Null、大 Hash 优先用 HSCAN。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询