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

📅 2026/7/4 9:05:30 👁️ 阅读次数 📝 编程学习
Redis 五大数据结构及使用场景

一句话

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


1. String(字符串)

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

常用命令: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 秒过期)
SessionSET session:abc123 '{"userId":1001}' EX 1800

2. Hash(哈希)

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

常用命令: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 存对象

String 方式: SET user:1001 '{"name":"Alice","age":30}' → 改一个字段要序列化整个对象再写回去 Hash 方式: HSET user:1001 name Alice HSET user:1001 age 30 → 改一个字段只需要 HSET 单个字段,更灵活更省内存

3. List(列表)

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

常用命令: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(集合)

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

常用命令: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 自动排序。

常用命令: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%,只占 12KBUV 统计
Geo基于 ZSet 实现,存储经纬度附近的人(GEORADIUS cities 116.40 39.90 100 km

7. 底层数据结构总结

面试可能追问底层实现:

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

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


🎙 面试回答模板

"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