Redis 常用8 种数据结构:String、List、Hash、Set、ZSet、Geo、Bitmap、HyperLogLog,附带底层、用法、典型场景。
一、1. String(字符串)
底层
简单动态字符串 SDS,最大 512MB。
常用命令
set / get / mset / mget / incr / decr / setnx / expire
应用场景
缓存:用户信息、商品数据、接口结果(最常用)
计数器:文章阅读量、点赞数、访问次数
分布式锁:setnx + expire 实现简单锁
限流:IP 限流、接口防刷
全局唯一 ID:incr 自增生成 ID
会话存储:登录 token、session
二、2. List(列表)
底层
双向链表,头尾操作极快,中间访问慢。
常用命令
lpush / rpush / lpop / rpop / lrange / brpop(阻塞弹出)
应用场景
消息队列 / 简易队列:lpush + rpop
阻塞队列:brpop 实现简单延时/消费队列
时间线、信息流:朋友圈、动态列表、评论列表
栈:lpush + lpop
三、3. Hash(哈希)
底层
ziplist / hashtable,field-value 结构。
常用命令
hset / hget / hmset / hmget / hincrby / hdel
应用场景
存储对象:用户信息、商品信息(比 String 更省内存)
购物车:用户ID→商品ID→数量
短字段聚合数据:多个小字段统一管理
对比:存单个对象优先 Hash,不要拆多个 String。
四、4. Set(集合)
底层
intset / 哈希表,无序、去重。
常用命令
sadd / smembers / sismember / sinter / sunion / sdiff / spop
应用场景
去重:访客 IP 去重、点赞用户去重
交集/并集/差集:
◦ 共同好友、共同关注
◦ 好友推荐、粉丝对比
随机抽奖:spop 随机弹出中奖用户
标签系统:文章/用户标签
五、5. ZSet(有序集合 / Sorted Set)
底层
ziplist / 跳表(skiplist),去重 + 按 score 排序。
常用命令
zadd / zrange / zrevrange / zrank / zrem / zscore
应用场景(高频考点)
排行榜:热度榜、积分榜、销量榜、直播间榜单
延时队列:score 存时间戳,轮询取到期任务
带权重排序:优先队列、任务权重排序
范围查询:按分数区间筛选数据
六、6. Bitmap(位图)
本质还是 String,按位操作。
常用命令
setbit / getbit / bitcount
应用场景
签到统计:用户每日签到(1 位代表 1 天)
活跃状态:用户在线/离线标记
海量布尔值统计(极度省内存)
七、7. HyperLogLog
基数统计,概率算法,有误差(0.81%),极小内存统计海量去重数量。
常用命令
pfadd / pfcount / pfmerge
应用场景
页面 UV 统计(独立访客数)
海量数据去重计数(不计明细,只算总数)
特点:只存数量,不存原始数据。
八、8. Geo(地理位置)
基于 ZSet 实现,存储经纬度。
常用命令
geoadd / geohash / geopos / geodist / georadius
应用场景
附近的人 / 附近门店
距离计算、范围查找
二、场景选型速查表(面试直接背)
• 单纯缓存、计数器、分布式锁、限流 → String
• 对象、购物车、多字段实体 → Hash
• 队列、栈、信息流、消息队列 → List
• 去重、交集并集、好友、标签、抽奖 → Set
• 排行榜、延时队列、有序任务 → ZSet
• 签到、布尔状态、海量标记 → Bitmap
• 大数据量 UV、独立访客计数(允许误差)→ HyperLogLog
• 经纬度、附近位置 → Geo
三、高频面试补充
List 为什么适合做队列?
双向链表,头尾 O(1),阻塞命令 brpop 可实现简单消息队列。ZSet 底层为什么用跳表不用红黑树?
跳表范围查询、排序、区间遍历更优,实现简单,内存友好。Hash 与 String 存对象区别?
Hash 可单独更新某个字段,省内存;String 需要整存整取。HyperLogLog 误差?
标准误差 0.81%,适合统计量,不要求绝对精确。