第21章:高级类型总结与底层原理
21.1 Redis 八种数据类型全景图
Redis 数据类型
├── String → 缓存、计数器、分布式锁
├── Hash → 用户信息、购物车、配置
├── List → 消息队列、最新列表
├── Set → 标签、共同好友、抽奖
├── ZSet → 排行榜、延时队列
├── Bitmap → 签到、在线状态
├── HyperLogLog → UV统计、去重计数
└── Stream → 可靠消息队列
└── Geo → 附近的人(基于ZSet)21.2 底层数据结构
| 结构 | 适用类型 | 复杂度 | 说明 |
|---|---|---|---|
| SDS | String | O(1) len | 二进制安全动态字符串 |
| hashtable | Hash, Set | O(1) 查找 | 标准哈希表 |
| listpack | Hash/Set/ZSet(小) | O(N) | Redis 7.0 替代 ziplist |
| skiplist | ZSet(大) | O(logN) | 多层索引,二分查找 |
| quicklist | List | O(N) | ziplist 组成的双向链表 |
| intset | Set(纯数字+小) | O(logN) | 有序整数数组 |
为什么 ZSet 用跳表不用红黑树?
跳表:
- 实现简单(100行代码 vs 红黑树 300+ 行)
- 支持范围查询(ZRANGEBYSCORE 天然支持)
- 平均 O(logN),概率平衡(不需要旋转)21.3 选型决策树(完整版)
需要持久化消息队列?
├── 是 → Stream
└── 否 → 数据需要排序?
├── 是 → 需要唯一?
│ ├── 是 → ZSet(排行榜、延时队列)
│ └── 否 → List(消息队列、最新列表)
└── 否 → 需要唯一?
├── 是 → 需要集合运算?
│ ├── 是 → Set(标签、共同好友)
│ └── 否 → Hash(对象存储)
└── 否 → 需要去重计数?
├── 是 → HyperLogLog(UV统计)
└── 否 → 需要位操作?
├── 是 → Bitmap(签到)
└── 否 → String(缓存、计数器、锁)本章小结
- 8 种数据类型,6 种底层结构
- ZSet 用跳表:简单 + 范围查询 + O(logN)
- 小对象自动用紧凑结构(listpack/intset)节省内存
- 选型决策树覆盖所有场景
练习题
- 画出 Redis 8 种数据类型与 6 种底层结构的对应关系。
- 用选型决策树为以下场景选型:商品库存、用户积分排名、附近商家、消息通知。
- (思考题)Dict 的渐进式 rehash 是什么?为什么 Redis 不一次性 rehash?