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 组合

最佳实践建议

  1. 优先用 Hash 存对象:比 String 存 JSON 更节省内存且支持字段级操作
  2. 排行榜用 ZSet:天然支持排序和范围查询
  3. UV 统计用 HyperLogLog:12KB 搞定上亿数据去重
  4. 签到用 Bitmap:极致节省内存
  5. 消息队列:简单场景用 List,复杂场景用 Stream
最后修改:2026 年 03 月 27 日
如果觉得我的文章对你有用,请随意赞赏