Redis 提供了丰富的数据结构,可以分为 5 种基础数据类型 和 3 种高级/特殊数据类型。
Redis 数据结构总览
| 类型 | 名称 | 特点 | 典型应用场景 |
|---|---|---|---|
| 基础类型 | |||
String | 字符串 | 二进制安全,可存储文本、数字、二进制数据 | 缓存、计数器、分布式锁、Session |
Hash | 哈希 | 键值对集合,适合存储对象 | 用户信息、购物车、对象缓存 |
List | 列表 | 有序、可重复、双向链表 | 消息队列、最新列表、时间线 |
Set | 集合 | 无序、不重复 | 标签、共同好友、抽奖 |
ZSet (Sorted Set) | 有序集合 | 有序、不重复、带分数 | 排行榜、延迟队列、优先级队列 |
| 高级类型 | |||
Bitmap | 位图 | 基于 String 的位操作 | 用户签到、活跃统计、状态标记 |
HyperLogLog | 基数统计 | 概率算法,极低内存占用 | UV 统计、去重计数 |
Geo | 地理位置 | 基于 ZSet 封装 | 附近的人、地理位置查询 |
Stream | 流 | 消息流,支持消费者组 | 消息队列、事件溯源 |
5 种基础数据类型详解
1️⃣ String(字符串)
特点:
- 最基础的数据类型
- 二进制安全(可存文本、图片、序列化对象)
- 最大容量 512MB
- 支持原子增减操作
底层实现:SDS(Simple Dynamic String)
struct sdshdr {
int len; // 已使用长度
int free; // 剩余空间
char buf[]; // 字符数组
};常用命令:
SET key value
GET key
INCR key # 自增 1
DECR key # 自减 1
INCRBY key 10 # 自增 10
SETEX key 10 value # 设置并过期(10秒)
MSET k1 v1 k2 v2 # 批量设置应用场景:
- ✅ 缓存热点数据
- ✅ 计数器(点赞数、访问量)
- ✅ 分布式锁(
SETNX) - ✅ Session 共享
2️⃣ Hash(哈希)
特点:
- 键值对集合,适合存储对象
- 可单独修改某个字段
- 节省内存(相比 String 存储 JSON)
底层实现:ZipList/ListPack(小数据) + HashTable(大数据)
常用命令:
HSET user:1 name "张三" age 25
HGET user:1 name
HMSET user:1 name "李四" age 26 city "北京"
HMGET user:1 name age
HGETALL user:1
HDEL user:1 age
HINCRBY user:1 age 1应用场景:
- ✅ 用户信息存储
- ✅ 电商购物车
- ✅ 文章元数据
3️⃣ List(列表)
特点:
- 有序、可重复
- 支持头尾插入/弹出
- 可实现栈和队列
底层实现:QuickList(ZipList + 双向链表)
常用命令:
LPUSH mylist a b c # 左侧插入
RPUSH mylist d e # 右侧插入
LPOP mylist # 左侧弹出
RPOP mylist # 右侧弹出
LRANGE mylist 0 -1 # 查看全部
LLEN mylist # 获取长度
LINDEX mylist 0 # 获取指定索引应用场景:
- ✅ 消息队列(
LPUSH+BRPOP) - ✅ 最新列表(微博时间线)
- ✅ 栈/队列实现
4️⃣ Set(集合)
特点:
- 无序、不重复
- 支持交集、并集、差集运算
底层实现:HashTable / IntSet(整数集合)
常用命令:
SADD tags article1 "java" "redis" "mysql"
SMEMBERS tags article1
SISMEMBER tags article1 "java"
SREM tags article1 "mysql"
SCARD tags article1 # 获取元素数量
# 集合运算
SINTER set1 set2 # 交集(共同好友)
SUNION set1 set2 # 并集
SDIFF set1 set2 # 差集应用场景:
- ✅ 标签系统
- ✅ 共同好友/关注
- ✅ 抽奖(
SPOP随机抽取) - ✅ 点赞/收藏(去重)
5️⃣ ZSet(Sorted Set,有序集合)
特点:
- 有序、不重复
- 每个元素关联一个分数(score)
- 按分数排序
底层实现:SkipList(跳表)+ HashTable
常用命令:
ZADD leaderboard 100 "user1" 200 "user2" 150 "user3"
ZRANGE leaderboard 0 -1 WITHSCORES # 正序排名
ZREVRANGE leaderboard 0 -1 WITHSCORES # 倒序排名(排行榜)
ZSCORE leaderboard "user1"
ZREM leaderboard "user1"
ZCARD leaderboard
ZCOUNT leaderboard 100 200 # 分数范围内的数量
ZRANK leaderboard "user1" # 获取排名应用场景:
- ✅ 排行榜(游戏、销售)
- ✅ 延迟队列(score = 执行时间戳)
- ✅ 优先级队列
- ✅ 带权重的推荐系统
3 种高级数据类型
6️⃣ Bitmap(位图)
本质:基于 String 的位操作
常用命令:
SETBIT sign:2026-02-24 0 1 # 用户 0 签到
SETBIT sign:2026-02-24 5 1 # 用户 5 签到
GETBIT sign:2026-02-24 0 # 查询用户 0 是否签到
BITCOUNT sign:2026-02-24 # 统计当天签到人数
BITOP AND dest src1 src2 # 位运算应用场景:
- ✅ 用户签到(1 亿用户仅需 ~12MB)
- ✅ 活跃用户统计
- ✅ 状态标记(在线/离线)
7️⃣ HyperLogLog
本质:概率算法,用于基数统计(去重计数)
特点:
- 极低内存占用(固定 12KB)
- 允许少量误差(约 0.81%)
常用命令:
PFADD uv:2026-02-24 user1 user2 user3
PFCOUNT uv:2026-02-24 # 统计 UV
PFMERGE dest src1 src2 # 合并多个 HLL应用场景:
- ✅ 网站 UV 统计
- ✅ 海量数据去重计数
8️⃣ Geo(地理位置)
本质:基于 ZSet 封装
常用命令:
GEOADD cities 116.40 39.90 "北京" 121.47 31.23 "上海"
GEODIST cities "北京" "上海" km
GEORADIUS cities 116.40 39.90 500 km # 500km 内的城市
GEOHASH cities "北京"应用场景:
- ✅ 附近的人
- ✅ 附近的服务/商家
- ✅ 物流轨迹
9️⃣ Stream(流)
特点:
- 类似 Kafka 的消息流
- 支持消费者组、消息确认
- Redis 5.0+ 引入
常用命令:
XADD mystream * name "Alice" age 25
XREAD COUNT 2 STREAMS mystream 0
XGROUP CREATE mystream group1 0
XREADGROUP GROUP group1 consumer1 STREAMS mystream >
XACK mystream group1 message_id应用场景:
- ✅ 消息队列(替代部分 Kafka 场景)
- ✅ 事件溯源
- ✅ 日志收集
数据结构选择指南
| 需求 | 推荐数据结构 |
|---|---|
| 简单缓存 | String |
| 对象存储 | Hash |
| 消息队列 | List / Stream |
| 排行榜 | ZSet |
| 去重统计 | Set / HyperLogLog |
| 签到/状态 | Bitmap |
| 地理位置 | Geo |
| 复杂对象 + 排序 | ZSet + Hash 组合 |
最佳实践建议
- 优先用 Hash 存对象:比 String 存 JSON 更节省内存且支持字段级操作
- 排行榜用 ZSet:天然支持排序和范围查询
- UV 统计用 HyperLogLog:12KB 搞定上亿数据去重
- 签到用 Bitmap:极致节省内存
- 消息队列:简单场景用
List,复杂场景用Stream