一、前言:Redis 不只是"缓存工具"
很多人认为 Redis 只是用来做缓存的,其实它是一个功能强大的内存数据结构服务器 。
Redis 提供了 5 种核心数据类型,每种都针对特定场景做了深度优化:
- 缓存用户信息?用 Hash
- 实现消息队列?用 List
- 做共同好友推荐?用 Set
- 打造实时排行榜?用 ZSet(Sorted Set)
掌握这些数据结构,你才能真正发挥 Redis 的威力!
本文将带你:
✅ 深入理解五大基本数据类型的内部结构
✅ 掌握常用命令与操作示例
✅ 结合真实业务场景说明用途
✅ 避开常见使用误区
二、String(字符串)------ 最基础但最常用
🔹 特点
- 最简单的 Key-Value 结构
- Value 可以是字符串、数字、甚至二进制数据(如图片)
- 支持 原子自增/自减 (
INCR/DECR)
🔧 常用命令
bash
SET user:1001 "张三"
GET user:1001
INCR page_view:home # 页面访问计数 +1
SETEX token:abc123 3600 "user_data" # 带过期时间
🎯 典型场景
- 缓存简单对象(如用户昵称、配置项)
- 分布式计数器(秒杀库存、接口限流)
- 分布式锁 (配合
SET key value NX EX)
💡 技巧:用
INCRBY实现批量加减,避免多次网络往返。
三、Hash(哈希)------ 存储对象的首选
🔹 特点
- 类似编程语言中的 Map / Dictionary
- 一个 Key 对应多个字段(field)和值(value)
- 适合存储结构化对象,避免序列化整个对象
🔧 常用命令
bash
# 存储用户信息
HSET user:1001 name "张三" age 28 city "北京"
# 获取单个字段
HGET user:1001 name
# 获取所有字段
HGETALL user:1001
# 原子递增
HINCRBY user:1001 login_count 1
🎯 典型场景
- 用户资料存储(无需每次读取整个对象)
- 商品属性(颜色、尺寸、库存等)
- 会话状态管理
✅ 优势:比 String 存 JSON 更节省内存,且支持字段级更新。
四、List(列表)------ 双向链表实现的队列
🔹 特点
- 底层是 快速列表(quicklist),由 ziplist + linkedlist 优化而成
- 支持从头部或尾部插入/弹出元素
- 可用于实现栈、队列、阻塞队列
🔧 常用命令
bash
# 从左侧推入
LPUSH news:list "头条新闻1"
LPUSH news:list "头条新闻2"
# 从右侧弹出(先进先出)
RPOP news:list
# 获取最新5条
LRANGE news:list 0 4
# 阻塞式弹出(等待消息)
BRPOP task:queue 10 # 等待10秒
🎯 典型场景
- 消息队列(轻量级任务分发)
- 最新动态/评论列表(如朋友圈 feed 流)
- 秒杀商品库存队列
⚠️ 注意:List 不适合大数据量随机访问(
LINDEX时间复杂度 O(N))。
五、Set(集合)------ 自动去重的无序集合
🔹 特点
- 元素唯一(自动去重)
- 无序(不保证插入顺序)
- 支持集合运算:交集、并集、差集
🔧 常用命令
bash
# 添加标签
SADD user:1001:tags "科技" "篮球" "电影"
# 判断是否包含
SISMEMBER user:1001:tags "篮球"
# 获取所有标签
SMEMBERS user:1001:tags
# 计算两个用户的共同兴趣
SINTER user:1001:tags user:1002:tags
🎯 典型场景
- 用户标签系统
- 共同好友/关注推荐
- 抽奖去重(确保每人只中一次)
💡 性能:
SADD/SISMEMBER时间复杂度为 O(1),极快!
六、ZSet(Sorted Set,有序集合)------ 带权重的集合
🔹 特点
- 每个成员(member)关联一个分数(score)
- 元素按 score 自动排序
- 支持范围查询(如 Top N、区间查找)
🔧 常用命令
bash
# 添加成员(score 可为整数或浮点)
ZADD game:rank 95 "玩家A"
ZADD game:rank 98 "玩家B"
ZADD game:rank 92 "玩家C"
# 获取排名前3(从高到低)
ZREVRANGE game:rank 0 2 WITHSCORES
# 获取某玩家的分数
ZSCORE game:rank "玩家A"
# 获取分数在 90~100 之间的玩家
ZRANGEBYSCORE game:rank 90 100
🎯 典型场景
- 游戏积分排行榜
- 延迟任务队列(score = 执行时间戳)
- 带权推荐系统(如热度 + 时间衰减)
⚡ 核心优势:插入、删除、查询 Top K 的时间复杂度均为 O(log N)!
七、底层实现简析(拓展知识)
| 数据类型 | 底层编码(encoding) | 说明 |
|---|---|---|
| String | int / raw / embstr | 小整数直接存指针,短字符串用 embstr 优化 |
| Hash | ziplist / hashtable | 元素少时用 ziplist 节省内存 |
| List | quicklist | ziplist 的双向链表,兼顾内存与性能 |
| Set | intset / hashtable | 全为整数且数量少时用 intset |
| ZSet | ziplist / skiplist | 少量元素用 ziplist,多则用跳表(skiplist) |
📌 Redis 会根据数据规模自动切换编码,无需手动干预。
八、常见误区与最佳实践
❌ 误区 1:用 String 存整个 JSON 对象
问题 :更新单个字段需全量反序列化+写回
建议 :改用 Hash,字段级操作更高效
❌ 误区 2:在 List 中频繁随机访问
问题 :
LINDEX是 O(N),大数据量会卡顿
建议 :如需索引,考虑用 ZSet + 自增 ID 模拟
❌ 误区 3:ZSet 存超大集合(百万级)
问题 :内存占用高,范围查询变慢
建议 :分片(如按天分 key:rank:20251103)
✅ 最佳实践:
- Key 命名规范 :
业务:实体:id(如user:profile:1001) - 设置 TTL:避免内存无限增长
- 避免 Big Key:单个 value 不超过 10KB,List/Set/ZSet 元素不超过 5000
九、结语
感谢您的阅读!如果你有任何疑问或想要分享的经验,请在评论区留言交流!