外观
一句话答案
五种基本类型:String(SDS)、List(quicklist)、Hash(ziplist/hashtable)、Set(intset/hashtable)、ZSet(ziplist/skiplist+dict)。
核心要点
| 类型 | 底层编码 | 典型场景 |
|---|---|---|
| String | SDS(简单动态字符串) | 缓存对象、计数器、分布式锁、Session 存储 |
| Hash | listpack(小量)/ hashtable(大量) | 对象属性存储(用户信息)、购物车 |
| List | listpack(小量)/ quicklist(大量) | 消息队列、最新动态列表、任务队列 |
| Set | listpack(小量)/ hashtable(大量) | 去重(用户抽奖、UV 统计)、共同好友、标签 |
| ZSet(SortedSet) | listpack(小量)/ skiplist+hashtable(大量) | 实时排行榜、延迟队列、带权重的优先级队列 |
各类型典型命令与场景:
String:
bash
SET key value EX 60 # 缓存,60s 过期
INCR page_views # 原子计数器
SETNX lock_key uuid # 分布式锁(原子性加锁)Hash:
bash
HSET user:1001 name "Alice" age 25 city "Beijing"
HGET user:1001 name
# 优势:比 String 存 JSON 更节省内存,支持单字段更新List:
bash
LPUSH queue task1 # 生产者左推
BRPOP queue 0 # 消费者右取(阻塞等待)
LRANGE feed:1001 0 9 # 最新 10 条 Feed 流Set:
bash
SADD lottery:users user1 user2 # 参与抽奖
SRANDMEMBER lottery:users 1 # 随机抽取1人
SINTER follows:A follows:B # A 和 B 的共同关注ZSet:
bash
ZADD leaderboard 1000 user1 900 user2 # 排行榜写入
ZREVRANGE leaderboard 0 9 WITHSCORES # 取 top10
ZADD delay_queue <timestamp> task_id # 延迟队列(score=执行时间戳)追问与易错
追问方向:
- ZSet 为什么用跳表不用红黑树?(实现简单/范围查询方便/并发友好)
- String 能存多大?(512MB,但建议 <10KB)
- Hash 什么时候从 ziplist 转为 hashtable?(元素>128 或单元素>64B)
易错点:
- ❌ "Redis 的 List 就是链表"——JDK 版本不同实现不同,3.2+ 是 quicklist(ziplist+双向链表)
- ❌ 忽略底层编码的自动转换——小数据量用紧凑编码,超过阈值自动转
💡 记忆锚点
底层编码"小紧凑大转换":数据少时用listpack省内存(住小房间),数据多了自动搬进hashtable/skiplist(住大别墅)。ZSet最特殊——同时住两套房:skiplist管排序,hashtable管O(1)查分数。