Redis 深度原理:为什么 Hash 比 String 更省内存?一篇讲透底层存储与优化
Redis 深度原理:为什么 Hash 比 String 更省内存?一篇讲透底层存储与优化
前言
在使用的 Redis 实际项目里,大家一定都听过一句话:
存结构化对象时尽量用 Hash,别用一堆 String,更省内存。
但很少有人把真正原理讲清楚:
同样是存用户信息,Hash 凭什么更省空间?
省的到底是哪部分内存?
什么时候用 Hash,什么时候必须用 String?
本文从 Redis 底层结构、元数据开销、序列化冗余、ziplist 压缩 四个角度,把 Hash 比 String 省内存的本质一次性讲明白。
一、存储方式的区别
假设我们要存一个User对象:
User{
id: 1001,
name: "zhangsan",
age: 23
}
1、String方式
很多人喜欢这么存:
user:1001:id → "1001"
user:1001:name → "zhangsan"
user:1001:age → "23"
一个对象使用多个独立的Key存储,这是最浪费的写法。
2、Hash方式
user:1001 → {
id:1001,
name:"zhangsan",
age:23
}
一个对象使用一个Key
到这里,Hash的优势显而易见了,接下来,我们看看Hash节省空间的核心原理
二、Hash更省的3大核心
1、减少元数据开销(最主要原因)
Reids中每一个key都要存key名字、过期时间、类型信息、指针、引用计数、
字典 Entry 结构,所以一个空key就占用大约36~40字节
而一个String为3个字段,即3个key,约为120字节,而一个Hash只占用一个key,所以Hash的优势显而易见。
2、避免序列化带来的冗余开销
假设使用String存储JSON格式数据,结果如下:
user:1001 → "{id:1001, name:\"zhangsan\", age:23}"
其中 { } " 等都是浪费,带来过多冗余信息
3、Hash特权ziplist
Redis 对 Hash 做了针对性优化:当 Hash 满足以下两个默认条件时,会使用ziplist(压缩列表) 存储,而非普通的哈希表:
字段数量 ≤ 512(可通过 hash-max-ziplist-entries 配置)
单个字段值 ≤ 64 字节(可通过 hash-max-ziplist-value 配置)
ziplist 的优势:
连续内存块存储,无链表指针、哈希表桶等额外开销;
字段名和字段值紧凑排列,内存利用率接近理论最优;
相比普通哈希表,ziplist 可减少约 70% 的内存占用;
当 Hash 超出上述阈值时,会自动切换为普通哈希表,此时空间优势会减弱,但仍比 String 方式节省元数据和键名开销。
三、总结
1、Hash为什么省内存: 减少key元数据的开销,避免键名重复,无序列化冗余,小Hash可以用ziplist压缩;
2、选型原则: 结构化小对象用 Hash,需独立过期 / 原子操作 / 存大数据用 String;
更多推荐




所有评论(0)