Redis 中常见的数据类型有哪些?
- 标签:后端、Redis
🏛 业务架构师
八种核心类型我按对应的业务模式讲——用对类型等于省掉一次自研:
- String:单值缓存(验证码、token)、计数器(incr)、分布式锁;
- Hash:字段级更新的对象——购物车(商品 ID→数量,加减单个商品不动整个车)、用户画像。对比"整存 JSON 字符串",避免读一个字段拉全量、改一个字段写全量;
- List:消息流、最新动态(lpush+ltrim 保留前 N 条)、简单队列;
- Set:无序去重——抽奖名单、标签、共同关注(sinter 交集做"可能认识的人");
- ZSet:带排序的业务——排行榜(score 即热度/积分/价格)、延时队列(score 存执行时间,zrangebyscore 捞到期任务)、权重随机;
- Bitmap:海量布尔状态——日活/签到(1 亿用户一天约 12MB,setbit 一位一个用户)、布隆过滤器的地基;
- HyperLogLog:海量计数允许 0.81% 误差——UV 统计的标准答案,一个 key 十几 KB 数十亿独立访客;
- GEO:附近的人/店(geohash 编码进 ZSet)。
两个业务判断经验:
- 类型选错是隐性成本:见过用 String 存 Hash 场景的,每次更新全量序列化,大对象网络与 CPU 双重浪费;也见过为"精确"用 Set 统计 UV 的,内存烧了几十 GB——用 12KB 的 HyperLogLog 换 0.81% 误差,是划算的交易;
- 高阶结构是现成的中间件:布隆过滤器、延迟队列、限流(Lua+ZSet)这些类型组合出来就是能力,先查 Redis 能不能做,再考虑引新组件——每引入一个新中间件,运维面就宽一寸。
一句话:Redis 是"数据结构即服务",业务建模时让数据形态匹配结构,是成本最低的优化。
🏗 系统架构师
我按"5 种基础 + 3 种扩展"回答,并带上典型用途:
基础类型:
- String:缓存对象 JSON、计数器(INCR 原子计数)、分布式锁(SET NX)、全局 ID 片段;二进制安全,最大 512MB;
- Hash:对象字段级存取(HSET user:1 name x age 20),局部读写省流量,适合购物车(field=商品,value=数量);
- List:双向链表,消息队列(LPUSH/BRPOP 阻塞队列)、时间线、最新列表;
- Set:无序去重,标签、共同关注(SINTER 交集)、抽奖去重、抽奖弹幕;
- ZSet:带 score 排序,排行榜、延迟队列(score=执行时间戳 + ZRANGEBYSCORE 轮询)、范围检索(按时间线索引)。
扩展类型(高版本,实战加分):
- BitMap:签到打卡、活跃标记,1 亿用户在线状态约 12MB;
- HyperLogLog:UV 统计,亿级基数去重仅 12KB,标准误差 0.81%;
- GEO:附近的人/店(GEOSEARCH);
- Stream(5.0):持久化消息队列,消费组语义。
选型原则:先语义匹配(排序用 ZSet、去重用 Set),再算内存账(大 Hash 用 field 拆分防 big key),我把"类型选择 + key 设计规范"写进团队 Redis 使用规约,从源头减少滥用。
💻 全栈开发专家
五大基础类型 + 四个扩展,我按"实际用来干嘛"过:
- String:缓存对象 JSON、计数器(INCR)、分布式锁(SET NX EX)、全局 ID。底层 SDS,embstr/int 编码自适应。
- List:消息队列(lpush + brpop 阻塞消费)、最新动态列表。底层 quicklist(ziplist 串成的链)。
- Hash:对象属性级读写(购物车:hset cart:uid sku_1 2),比整存 String 省"改一个字段要整个反序列化"的开销。小 hash 用 ziplist/listpack。
- Set:去重、共同好友(SINTER)、抽奖(SPOP)、点赞集合。
- ZSet:排行榜、延迟队列(score 存执行时间,ZRANGEBYSCORE 轮询)、滑动窗口限流。底层 listpack 或 skiplist+dict 双结构。
- BitMap:签到(SETBIT day:202610 1688 1,10MB 记 1 亿用户 30 天)、活跃统计,极致省空间。
- HyperLogLog:UV 统计,固定 12KB 出 0.81% 误差的基数估计,海量去重的性价比之王。
- GEO:附近的人(GEOSEARCH),底层 zset 的 geohash 编码。
- Stream:持久化消息队列(XADD/XREADGROUP + 消费组 + ACK),比 List 可靠。
工程习惯:key 命名 业务:对象:id,一律带 TTL;Set/ZSet 大小要监控,防止无界增长变 bigkey。