Redis 常见数据类型可以按“结构 + 场景”来记。
| 类型 | 结构特点 | 常见用途 |
|---|---|---|
| String | 字符串、数字、JSON 都可以存 | 缓存、计数器、分布式锁、库存 |
| Hash | 类似 Map<String, Object> | 存对象字段,比如用户信息、店铺信息 |
| List | 有序列表,可左右 push/pop | 消息队列、时间线,实际项目中现在更常用 MQ/Stream |
| Set | 无序、不重复集合 | 点赞、收藏、关注、共同关注 |
| ZSet | 有序集合,元素不重复,每个元素有 score | 排行榜、热度榜、滑动窗口限流 |
| Bitmap | 位图,本质还是 String | 签到、活跃状态统计 |
| HyperLogLog | 基数统计 | UV 统计,允许少量误差 |
| GEO | 地理位置索引 | 附近商户、距离计算 |
| Stream | 消息流 | 异步消息队列、消费组 |
1. String
最基础的数据类型。
常见命令:
set key value
get key
incr key
decr key
setnx key value
expire key seconds
常见场景:
缓存店铺详情
缓存验证码
用户 token
分布式锁
秒杀库存扣减
计数器
比如:
shop:1 -> 店铺 JSON
seckill:stock:10 -> 100
login:token:xxx -> userId
2. Hash
适合存对象的多个字段。
hset user:1 name zhangsan age 20
hget user:1 name
hgetall user:1
可以理解为:
user:1
name -> zhangsan
age -> 20
优点是可以单独修改某个字段,不一定每次都序列化整个对象。
项目里如果要存用户信息、店铺基础字段,可以用 Hash;但很多项目为了开发简单,也会直接用 String 存 JSON。
3. List
List 是有序的,可以从左边或右边插入、弹出。
lpush queue a
rpop queue
blpop queue 10
可以做简单队列:
生产者 lpush
消费者 rpop
但 List 做消息队列不够完善,比如消息确认、重复消费、消费组这些能力弱,所以现在更推荐 Redis Stream 或专业 MQ。
4. Set
Set 是无序、不重复集合。
sadd user:like:1 shop1
sismember user:like:1 shop1
sinter follow:1 follow:2
适合:
点赞去重
收藏去重
关注列表
共同关注
标签集合
比如黑马点评原项目里的共同关注,就很适合用 Set 的交集:
sinter follows:user1 follows:user2
5. ZSet
ZSet 是有序集合,每个元素都有一个 score。
zadd rank 100 user1
zadd rank 200 user2
zrevrange rank 0 9 withscores
适合:
排行榜
热度榜
点赞排名
滑动窗口限流
你这个项目里的 Redis + Lua 滑动窗口限流,就可以用 ZSet 表示请求时间窗口:
key: rate:user:1
member: 请求唯一 id
score: 请求时间戳
每次请求时:
删除窗口外的数据
统计窗口内请求数
没超过阈值就放行并写入当前请求
超过阈值就拒绝
6. Bitmap
Bitmap 用 bit 位存状态,适合大量布尔值。
比如签到:
第 1 天签到 -> bit 0 = 1
第 2 天没签到 -> bit 1 = 0
第 3 天签到 -> bit 2 = 1
优点是省内存。
适合签到、活跃用户统计。
7. HyperLogLog
用于统计不重复数量,比如 UV。
pfadd uv user1 user2 user3
pfcount uv
它很省内存,但有误差,所以适合“可以接受少量误差”的统计场景。
8. GEO
GEO 用来存经纬度。
geoadd shop:geo 116.397 39.908 shop1
geosearch shop:geo fromlonlat 116.4 39.9 byradius 5 km
适合附近商户、附近门店、距离排序。
黑马点评里的“附近商户”就是 GEO 的典型场景。
9. Stream
Stream 是 Redis 提供的消息流类型,支持消息 ID、消费组、ACK。
xadd stream.orders * userId 1 voucherId 10
xreadgroup group g1 c1 count 1 streams stream.orders >
xack stream.orders g1 messageId
适合异步下单、消息队列。
不过如果系统已经引入 RocketMQ,核心异步链路一般会交给 RocketMQ。
面试回答版
Redis 常见数据类型有 String、Hash、List、Set、ZSet,还有 Bitmap、HyperLogLog、GEO、Stream。String 适合缓存、计数器、分布式锁和库存;Hash 适合存对象字段;List 可以做简单队列;Set 适合点赞、关注、共同关注这类去重集合;ZSet 适合排行榜和滑动窗口限流;Bitmap 适合签到;HyperLogLog 适合 UV 统计;GEO 适合附近商户;Stream 适合消息队列和消费组。
在点评项目里,店铺缓存可以用 String 存 JSON,附近商户可以用 GEO,共同关注可以用 Set,排行榜和限流可以用 ZSet,异步下单可以用 Stream 或 RocketMQ。