Skip to content
极高进阶

一句话答案

五种基本类型:String(SDS)、List(quicklist)、Hash(ziplist/hashtable)、Set(intset/hashtable)、ZSet(ziplist/skiplist+dict)。

核心要点
类型底层编码典型场景
StringSDS(简单动态字符串)缓存对象、计数器、分布式锁、Session 存储
Hashlistpack(小量)/ hashtable(大量)对象属性存储(用户信息)、购物车
Listlistpack(小量)/ quicklist(大量)消息队列、最新动态列表、任务队列
Setlistpack(小量)/ 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)查分数。