Redis 五大数据结构及使用场景

一句话

Redis 提供 5 种基本数据结构(String、Hash、List、Set、ZSet),外加 3 种高级结构(Bitmap、HyperLogLog、Geo),每种都针对特定场景优化。面试重点是知道​什么场景用什么结构​。


1. String(字符串)

最基本的数据类型,最大 512MB,可以是文本也可以是二进制。

text 复制代码
常用命令:SET / GET / MSET / MGET / INCR / DECR
底层数据结构:SDS(Simple Dynamic String),支持动态扩容,二进制安全
场景 示例
普通缓存 SET user:1001 '{"name":"Alice","age":30}'
计数器 INCR article:read:123(原子自增)
分布式锁 SET lock_key true NX EX 10(NX=不存在才设置,EX=10 秒过期)
Session SET session:abc123 '{"userId":1001}' EX 1800

2. Hash(哈希)

一个 key 对应多个 field-value,适合存储对象。

text 复制代码
常用命令:HSET / HGET / HMSET / HMGET / HDEL / HINCRBY
底层数据结构:ziplist(小数据量) → hashtable(大数据量)
场景 示例
对象缓存 HSET user:1001 name Alice age 30
购物车 HSET cart:1001 sku_123 2(field=商品 ID, value=数量)

String 存对象 vs Hash 存对象

text 复制代码
String 方式:
  SET user:1001 '{"name":"Alice","age":30}'
  → 改一个字段要序列化整个对象再写回去

Hash 方式:
  HSET user:1001 name Alice
  HSET user:1001 age 30
  → 改一个字段只需要 HSET 单个字段,更灵活更省内存

3. List(列表)

有序的字符串链表,两端插入弹出都是 O(1)。

text 复制代码
常用命令:LPUSH / RPUSH / LPOP / RPOP / LRANGE / BLPOP
底层数据结构:quicklist(ziplist + 双向链表)
场景 示例
消息队列 LPUSH queue:task task_001BRPOP queue:task 30(阻塞消费)
最新列表 LPUSH news:latest news_id+LTRIM news:latest 0 9(只保留最新 10 条)
栈/队列 LPUSH+RPOP=队列,LPUSH+LPOP=栈

4. Set(集合)

无序不重复的字符串集合,支持集合运算。

text 复制代码
常用命令:SADD / SREM / SMEMBERS / SISMEMBER / SINTER / SUNION / SDIFF
底层数据结构:intset(全是整数且数量少) → hashtable
场景 示例
点赞/标签 SADD news:123:liked user_456SISMEMBER news:123:liked user_456
共同关注 SINTER follow:A follow:B(A 和 B 的共同关注)
好友推荐 SDIFF follow:A follow:B(A 关注但 B 没关注的人)
去重 SADD unique:ids id1 id2 id3(自动去重)

5. ZSet(有序集合)

每个 member 关联一个 score,按 score 自动排序。

text 复制代码
常用命令:ZADD / ZREM / ZSCORE / ZRANGE / ZREVRANGE / ZINCRBY
底层数据结构:ziplist(少量数据) → skiplist + hashtable(跳表 + 哈希表)
场景 示例
排行榜 ZINCRBY rank:2024 player_789 10ZREVRANGE rank:2024 0 9 WITHSCORES
延迟队列 score=执行时间戳,定时扫描 score <= now 的任务
滑动窗口限流 score=时间戳,ZREMRANGEBYSCORE 清理过期记录

6. 三种高级结构(了解即可)

结构 原理 场景
Bitmap 操作字符串的每一位,极其省空间 用户签到(SETBIT sign:1001 100 1
HyperLogLog 概率数据结构,估算不重复元素数,误差 0.81%,只占 12KB UV 统计
Geo 基于 ZSet 实现,存储经纬度 附近的人(GEORADIUS cities 116.40 39.90 100 km

7. 底层数据结构总结

面试可能追问底层实现:

text 复制代码
String → SDS(动态字符串,预分配内存,减少 realloc)
Hash   → ziplist(元素少且小) → hashtable(元素多)
List   → quicklist(ziplist + 双向链表的折中方案)
Set    → intset(全是整数且 ≤ 512 个) → hashtable
ZSet   → ziplist(元素少) → skiplist + hashtable

核心思路:​数据少时用压缩结构省内存,数据多时切换到高效结构​。


🎙 面试回答模板

text 复制代码
"Redis 有 5 种基本数据结构。String 最通用,能做缓存、计数器、分布式锁;
Hash 适合存对象,比如用户信息或购物车,可以单独更新某个字段,
比 String 存整个 JSON 更灵活;List 是有序列表,可以当消息队列或最新消息列表;
Set 是无序不重复集合,支持交集并集差集,适合做点赞、标签、共同关注;
ZSet 是带分数的有序集合,最经典的场景就是排行榜。

另外还有 Bitmap 做签到、HyperLogLog 做 UV 统计、Geo 做附近的人,
这三种了解场景就行。

底层实现方面,Redis 会根据数据量自动选择压缩结构或高效结构,
数据少时用 ziplist/intset 省内存,数据多时切换到 hashtable/skiplist。"

参考来源

  • 01_Raw【原始素材】/notion 资料/Notion/任务/Redis核心数据结构实战+服务搭建.md
  • 01_Raw【原始素材】/notion 资料/Notion/任务/Redis7 底层数据结构解析.md
  • Redis 官方文档:Data types