为什么结构选择这么关键
Redis 的价值在于按访问模式挑对数据结构:string 做缓存与计数、hash 存对象字段、list 当队列、set 去重、zset 做排行与延时队列、bitmap 记签到、HyperLogLog 估基数、stream 做消息流。结构选错会同时增加内存占用与实现复杂度。
基本信息
| string | 缓存、计数器、分布式锁,最通用的结构 |
|---|---|
| hash | 对象字段级读写,避免整体序列化 |
| list | 轻量队列与最新列表,两端操作高效 |
| zset | 排行榜与延时队列,按分值排序取范围 |
| bitmap / HyperLogLog | 签到与基数估算,用极小空间换近似结果 |
| stream | 消息流与消费组,带未确认消息机制 |
典型使用场景
- 缓存对象字段:用 hash 只读写变化的那几个字段
- 计数与限流:string 的原子自增最直接
- 任务队列:简单队列用 list,需要确认与重试用 stream
- 排行榜与延时任务:zset 按分值排序取范围
- 去重与统计:精确去重用 set,基数估算用 HyperLogLog
各结构典型命令
各结构典型命令
INCR page:view:20261013 # string:原子计数
HSET user:7 name ann age 30 # hash:对象字段读写
LPUSH queue:jobs a b c # list:队列
SADD tags:1 db cache # set:去重集合
ZADD rank 120 u1 95 u2 # zset:排行榜
SETBIT sign:7 11 1 # bitmap:签到标记
PFADD uv:20261013 u1 u2 # HyperLogLog:UV 基数估算
XADD stream:orders * item apple qty 2 # stream:消息流
# 评估单个键的实际内存占用
MEMORY USAGE rank结构取舍
| 结构 | 典型用途 | 注意点 |
|---|---|---|
| string | 缓存、计数、分布式锁 | 整值读写,大 value 影响网络与内存 |
| hash | 对象字段级读写 | 字段很多时避免整个 HGETALL |
| list | 轻量队列、最新列表 | LINSERT 与 LREM 是线性操作 |
| zset | 排行榜、延时队列 | 成员与分值双存储,内存开销较高 |
| bitmap | 签到、活跃标记 | 稀疏大偏移会浪费内存 |
| HyperLogLog | UV 基数估算 | 固定小体积,存在标准误差 |
| stream | 消息流与消费组 | 需要处理未确认消息 |
小集合(小 hash、小 zset)在元素较少时会使用紧凑编码省内存,超过阈值后转成完整结构;阈值可在配置中查看,调整前先确认真实数据规模。
用 set 保存全量 UV 在大流量下内存增长很快,只需要基数估计时 HyperLogLog 更合适,但它是近似结果,不能用于精确对账。