Redis Hash

返回 Redis

Hash 将单个 key 映射为多个 field → value,适合表示对象属性(用户资料、商品 SKU 属性、购物车行)。等价于「一个 key 下的小字典」,比把整个对象 JSON 塞进 String 更便于按字段读写HINCRBY 原子加减。


完整命令表见 基础命令 · Hash

HSET user:1001 name Alice age 30 points 100
HGET user:1001 name
HINCRBY user:1001 points 10
HSCAN user:1001 0 COUNT 20

底层编码

条件编码说明
字段少、值短listpack(旧版 ziplist)内存紧凑
字段多或值长hashtable标准哈希表

阈值hash-max-listpack-entries / hash-max-listpack-value 配置变化。字段从 10 个涨到 5000 会触发编码升级,可能短暂阻塞。


典型场景

场景Key 示例设计要点
用户缓存user:{id}field = 属性名;TTL 设在整个 key
购物车cart:{userId}field = skuId,value = 数量;HINCRBY 改数量
会话session:{token}多字段存登录态,替代大 String JSON
计数分组stats:20240601field = 渠道/类型,value = 计数
步数(按日)step:20240601:{uid}单 field 或 String 亦可,见 排行榜与实时计数

Hash vs String(JSON)

维度HashString + JSON
改一个字段HSET / HGET O(1)读改写整段 JSON
部分读取原生支持需反序列化
嵌套结构扁平 field,或 value 再 JSON一层 JSON 更自然
内存多 field 有元数据单 blob 可能更省

分布式与集群注意

  • 整个 Hash 落在一个 key 的一个 slot(Cluster),不会按 field 分片。
  • 热 key:超大 Hash(百万 field)打在同一节点 → 用分片 key(cart:{uid}:0cart:{uid}:N)或改模型。
  • 禁止在生产对巨大 Hash 用 HGETALLKEYS — 阻塞单线程,见 Redis

与 ZSet 的配合

  • 排行榜用 ZSet(score 排序);Hash 存用户展示信息(user:{id}),榜只存 id + 分数,查榜后再 HMGET 批量补全昵称头像。

Spring Boot

redisTemplate.opsForHash().put("user:1001", "name", "张三");
redisTemplate.opsForHash().increment("user:1001", "points", 10L);
Map<Object, Object> map = redisTemplate.opsForHash().entries("user:1001");

详见 Redis 集成


相关链接