Appearance
Redis 数据结构与使用场景
这篇笔记专门整理 Redis 里最核心的一条主线:数据结构怎么选。
Redis 很多能力看起来像“命令很多”,但真正落到工程实践,最关键的问题其实是:当前这类数据,到底应该放成什么结构,才能既容易操作,又能保持性能稳定。
1. 🌟 为什么 Redis 的数据结构很重要
Redis 的优势不只是“在内存里”,还在于它提供了多种针对高频操作优化过的数据结构。
这意味着:
- 结构选对了,读写会很自然
- 结构选错了,代码会变别扭,性能也容易变差
例如排行榜用 ZSet 就很自然;如果硬用 String 加应用端排序,也不是不能做,但复杂度和性能都不会太友好。
所以 Redis 里的很多设计题,本质上不是“有没有办法实现”,而是:是不是选中了最贴合访问模式的数据结构。
2. 🌟 5 种基础类型
2.1 String
String 是 Redis 里最常见的类型,适合:
- 缓存单个值
- 计数器
- 分布式锁基础实现
- 简单标志位
常见场景:
- 商品详情缓存
- 短信验证码
- 点赞数、阅读数
它的优势是简单、通用,但如果一个对象字段很多、局部更新频繁,就不一定是最优选择。
2.2 Hash
Hash 更适合表示对象的多个字段,例如:
- 用户信息
- 配置项
- 订单摘要
它的好处是:
- 结构清晰
- 可以按字段更新
- 比把所有字段都硬塞成一个大 JSON 更容易做局部操作
2.3 List
List 适合按顺序维护一组元素,典型场景包括:
- 简单消息队列
- 最近访问记录
- 时间顺序消息流
但如果你既要顺序,又要去重,还要排序,List 往往就不是最贴切的结构了。
2.4 Set
Set 最适合这些问题:
- 去重
- 成员关系判断
- 交集、并集、差集计算
例如:
- 用户标签集合
- 已点赞用户集合
- 共同好友或共同关注分析
2.5 ZSet
ZSet 是带分数的有序集合,非常适合:
- 排行榜
- 按权重排序
- 延迟队列基础实现
- 优先级调度
它之所以经典,是因为它同时保留了:
- 成员唯一性
- 分数排序能力
- 范围查询能力
3. 🌟 不是只有 5 种:Redis 里还有几类非常常见的能力
3.1 Bitmap
Bitmap 很适合做大规模布尔位统计,例如:
- 用户签到
- 用户是否活跃
- 某天是否登录
它的核心价值是:用非常紧凑的空间表示大量 0/1 状态。
3.2 HyperLogLog
HyperLogLog 适合做近似去重统计,例如:
- UV 统计
- 独立访客数量估算
它的重点不在“绝对精确”,而在:
- 空间占用很小
- 可以接受一定误差
如果业务要求绝对精确去重,就不能直接用它替代普通集合。
3.3 GEO
GEO 适合位置类场景,例如:
- 附近门店
- 附近骑手
- 附近的人
它让 Redis 在轻量位置检索场景里也能承担一部分能力。
3.4 Stream
Stream 是 Redis 较新的重要能力之一,适合:
- 消息流
- 消费组
- 多消费者处理
它比简单的 List 更适合消息消费场景,但如果业务对消息可靠性、积压治理和生态要求特别高,通常还是要结合更专业的 MQ 做选型。
4. 一个更实用的结构选型表
| 需求 | 更适合的结构 | 原因 |
|---|---|---|
| 单值缓存、计数器 | String | 简单直接,通用性高 |
| 对象字段存储 | Hash | 字段级更新更自然 |
| 顺序消息或最近记录 | List | 天然有序 |
| 去重和集合关系 | Set | 成员唯一,集合运算方便 |
| 排行榜、权重排序 | ZSet | 有序且支持范围查询 |
| 海量布尔位状态 | Bitmap | 空间占用更紧凑 |
| 近似 UV 去重统计 | HyperLogLog | 低成本近似统计 |
| 附近位置检索 | GEO | 原生位置计算能力 |
| 消息流、消费组 | Stream | 更适合流式消费 |
5. 🌟 结构选型时最容易忽略的几个问题
5.1 不是能存进去就算合适
例如一个对象,理论上可以直接序列化成 String,也可以拆成 Hash。
区别不在“能不能存”,而在:
- 是否需要局部更新
- 是否需要按字段读取
- 是否追求结构清晰
5.2 排序需求通常决定你是否应该用 ZSet
很多设计一开始看起来是“只要存个集合”,但一旦业务开始要求:
- 按分数排名
- 查前 100 名
- 查某个分值区间
这时候 ZSet 往往就比 Set 或 List 更合适。
5.3 大量状态位不要滥用普通集合
像签到、活跃状态这类问题,如果用 Set 也能做,但数据量上来后,Bitmap 往往更省空间。
5.4 Stream 能解决一部分消息问题,但不等于通用 MQ
Stream 很强,但它更适合 Redis 生态内的轻量流式处理。
如果业务依赖复杂消息治理、超大堆积、跨系统可靠投递,仍然要结合专业 MQ 评估。
6. 一份实用的数据结构检查清单
可以优先检查这些问题:
- 这个结构是否贴合主要读写模式
- 是否需要排序、去重或范围查询
- 是否需要局部更新
- 是否有大规模布尔位或近似去重统计需求
- 这个结构在数据量上来后是否还稳定
Redis 数据结构设计真正的关键,不是记住多少命令,而是把“数据形态”和“访问模式”对齐起来。