设计 Redis 的 key 和 value ,有哪些原则?
# 一、Key 设计原则
核心是 “清晰、简洁、可维护、高性能”,避免 Key 混乱和 Redis 性能问题:
使用统一的命名规范:
采用 “业务模块:对象:唯一标识:属性” 的格式,明确 Key 的归属和含义,例如:
用户信息:
user:info:1001(1001 为用户 ID)商品库存:
goods:stock:2001(2001 为商品 ID)订单状态:
order:status:3001(3001 为订单 ID)
避免无意义的 Key(如
key1231),便于后期维护和排查问题。
Key 长度适中:
- 避免过长的 Key(如超过 100 字符):Redis 的 Key 存储在内存中,过长的 Key 会占用更多内存,且查询时网络传输开销大;
- 避免过短的 Key(如
u:1):可读性差,难以理解 Key 的含义。 - 推荐长度:10-50 字符,平衡可读性和内存占用。
避免特殊字符:
不使用空格、换行、
\0、:(若命名规范已用:,则避免额外使用)等特殊字符,这些字符可能导致 Redis 命令解析错误,或在某些客户端中显示异常。控制 Key 的数量:
- 避免单类 Key 数量过多(如超过 1000 万):Redis 的 Key 存储在字典中,过多 Key 会导致字典扩容频繁,影响性能;
- 解决方案:对大量 Key 进行分片(如按用户 ID 哈希分片,
user:info:1001:shard1),或使用 Hash 结构存储(将多个小 Key 合并为一个 Hash Key)。
设置合理的过期时间:
- 对临时数据(如验证码、会话信息)设置过期时间(
expire),避免 Redis 内存泄漏; - 对永久数据(如用户基础信息)不设置过期时间,但需定期清理无效数据(如用户注销后删除 Key)。
- 对临时数据(如验证码、会话信息)设置过期时间(
# 二、Value 设计原则
核心是 “紧凑存储、便于序列化、适配业务场景”,避免内存浪费和序列化 / 反序列化开销:
选择合适的数据结构:
根据业务场景选择 Redis 数据结构,避免 “用 String 存储复杂数据”:
- 存储对象(如用户信息):用 Hash(
hset user:info:1001 name "zhangsan" age 20),而非 String(存储 JSON 字符串),可单独更新某个字段,减少网络传输; - 存储列表(如商品评论):用 List(
lpush goods:comment:2001 "good"),支持顺序访问和分页; - 存储集合(如用户标签):用 Set(
sadd user:tag:1001 "student" "male"),支持去重和交集 / 并集操作; - 存储排序数据(如商品销量排名):用 ZSet(
zadd goods:rank 100 2001),支持按分数排序。
- 存储对象(如用户信息):用 Hash(
紧凑序列化:
若用 String 存储复杂数据(如 JSON、对象),选择紧凑的序列化方式:
- 对比 JSON 和 Protobuf:JSON 可读性强,但体积大;Protobuf 体积小(比 JSON 小 30%-50%),序列化速度快,适合高性能场景;
- 避免存储冗余数据:如用户信息中,只存储必要字段(
id、name、phone),不存储无关字段(如历史订单)。
控制 Value 大小:
- 避免 Value 过大(如超过 10MB):Redis 的 Value 过大,会导致网络传输慢(如读取一个 10MB 的 Value 需耗时较长),且 Redis 的内存分配和回收效率低;
- 解决方案:对大 Value 分片(如将大文件分成多个 1MB 的小 Value,用
file:1:part1、file:1:part2命名),或用 Redis Stream 存储大列表数据。
保持数据一致性:
- 若 Value 与数据库数据关联,需确保缓存与数据库的一致性(如更新数据库后,及时更新或删除缓存,避免缓存脏数据);
- 推荐策略:先更新数据库,再删除缓存(Cache-Aside Pattern),或使用 Canal 监听数据库 binlog,异步更新缓存。
避免存储敏感数据:
Redis 默认不加密,若 Value 包含敏感数据(如用户密码、银行卡号),需先加密(如 AES 加密)再存储,防止数据泄露。
上次更新: 12/30/2025