Redis 五大基础数据结构与应用场景
Redis 不仅是缓存,更是数据结构服务器。选对数据结构,能让业务代码事半功倍。
一、String(字符串)
最基础的数据结构,可存储字符串、数字、序列化对象。
SET name "小宇宙"
GET name
INCR counter
SETEX token 3600 "abc"
底层实现:SDS(Simple Dynamic String)
应用场景:
- 缓存对象(JSON 序列化)
- 计数器:
INCR/INCRBY - 分布式锁:
SETNX - 限流:
INCR+ 过期时间
// 简单计数器:统计文章阅读量
jedis.incr("article:read:1001");
二、List(列表)
双向链表,支持从两端插入/弹出。
LPUSH list "a" "b"
RPUSH list "c"
LPOP list
LRANGE list 0 -1
底层实现:QuickList(ziplist + linkedlist 的结合)
应用场景:
- 消息队列:
LPUSH+BRPOP - 文章列表:分页查询
- 最新动态:朋友圈、微博时间线
// 模拟消息队列
jedis.lpush("task:queue", "sendEmail:1001");
String task = jedis.brpop(0, "task:queue");
三、Hash(哈希)
键值对集合,适合存储对象。
HSET user:1001 name "小宇宙" age 18
HGET user:1001 name
HGETALL user:1001
HINCRBY user:1001 age 1
底层实现:ziplist(小) / hashtable(大)
应用场景:
- 对象存储(比 String + JSON 更高效)
- 购物车:
HSET cart:userId productId count - 配置中心
// 购物车
jedis.hset("cart:1001", "SKU001", "2");
jedis.hincrBy("cart:1001", "SKU002", 1);
四、Set(集合)
无序、不重复元素集合。
SADD tags "java" "redis" "mysql"
SMEMBERS tags
SISMEMBER tags "java"
SINTER set1 set2 # 交集
SUNION set1 set2 # 并集
SDIFF set1 set2 # 差集
底层实现:intset / hashtable
应用场景:
- 标签系统
- 共同关注、共同好友
- 抽奖:
SRANDMEMBER/SPOP - UV 统计(去重)
// 共同关注
jedis.sinter("follow:user:1001", "follow:user:1002");
五、ZSet(有序集合)
每个元素带 score,按 score 排序。
ZADD ranking 100 "小宇宙" 90 "小明" 95 "小红"
ZREVRANGE ranking 0 9 WITHSCORES # 前 10
ZINCRBY ranking 5 "小明"
底层实现:ziplist / skiplist + hashtable
应用场景:
- 排行榜(最经典)
- 延迟队列:score 为执行时间
- 热搜榜单
- 带权重的消息
// 文章排行榜
jedis.zincrby("article:hot", 1, "article:1001");
// 获取 Top 10
Set<Tuple> top10 = jedis.zrevrangeWithScores("article:hot", 0, 9);
六、特殊数据结构
除了五大基础结构,Redis 还提供:
| 结构 | 特点 | 场景 |
| ---- | ---- | ---- |
| Bitmap | 位操作 | 签到、活跃统计 |
| HyperLogLog | 去重统计(误差 0.81%) | UV 统计 |
| Geo | 地理位置 | 附近的人、商家 |
| Stream | 持久化消息队列 | 替代 MQ |
签到系统(Bitmap)
// 用户 1001 在 2026 年 6 月 24 日签到
// offset = (月份-1)*31 + 日,简化示例
jedis.setbit("sign:1001:202606", 24, true);
// 统计本月签到次数
jedis.bitcount("sign:1001:202606");
UV 统计(HyperLogLog)
// 12 万 UV 仅占用 12KB 内存
jedis.pfadd("uv:20260624", "user1", "user2", "user3");
long uv = jedis.pfcount("uv:20260624");
七、选型对比
| 需求 | 推荐 | 原因 |
| ---- | ---- | ---- |
| 简单缓存 | String | 简单直接 |
| 对象存储 | Hash | 字段独立读写 |
| 排序 | ZSet | 内置排序 |
| 去重 | Set / HyperLogLog | Set 精确,HLL 省内存 |
| 队列 | List / Stream | Stream 支持持久化 |
| 位运算 | Bitmap | 签到场景必备 |
八、小结
Redis 数据结构的设计哲学:为每个场景提供最合适的数据结构,避免在业务层做不必要的处理。
记住小宇宙的话:选择正确的数据结构,比写出更优雅的代码更重要。