06 其他数据类型概览
除了五大基本类型,Redis 还有几个"特种兵"类型,各自解决一类特定问题。 本章目标是混个脸熟:知道它们存在、知道什么时候该想起它们,用到时再查文档即可。
1. Bitmap(位图):超省内存的签到表
Bitmap 不是独立类型,它本质是把 String 当作一串二进制位(bit)来用,每个位只能是 0 或 1。
核心优势:极度省内存。 1 个用户 1 天的签到状态只占 1 bit,1 亿用户一天的签到只需约 12MB。
# 用户签到:user:sign:1001:2026-07,第 25 天(偏移量从0开始,用25表示26号)签到
127.0.0.1:6379> setbit user:sign:1001:2026-07 25 1
(integer) 0
# 查询某天是否签到
127.0.0.1:6379> getbit user:sign:1001:2026-07 25
(integer) 1
# 本月一共签到几天
127.0.0.1:6379> bitcount user:sign:1001:2026-07
(integer) 1
适用场景:签到打卡、用户在线状态、是否读过某消息——一切"亿级规模的是/否"问题。
2. HyperLogLog:亿级去重计数,只占 12KB
统计"今天有多少个不同的用户访问过"(UV),用 Set 可以做,但 1 亿用户的 Set 要占好几 GB 内存。
HyperLogLog 用概率算法解决这个问题:无论多少数据,固定只占约 12KB,代价是计数有约 0.81% 的误差。
# 记录访客(pf 开头,纪念发明者 Philippe Flajolet)
127.0.0.1:6379> pfadd uv:2026-07-26 user1 user2 user3 user1
(integer) 1
# 统计去重后的数量
127.0.0.1:6379> pfcount uv:2026-07-26
(integer) 3 # user1 重复,不重复计数
# 合并多天的统计
127.0.0.1:6379> pfmerge uv:week uv:2026-07-25 uv:2026-07-26
OK
适用场景:UV 统计、搜索关键词去重计数——数据量巨大、允许微小误差、只要数量不要明细的场景。 不适用:需要精确值,或需要知道"具体是谁"(HyperLogLog 无法取出元素)。
3. GEO:附近的人 / 附近的店
GEO 用于存储经纬度并做地理计算(底层基于 ZSet):
# 添加几个城市的坐标(经度 纬度 名字)
127.0.0.1:6379> geoadd cities 116.40 39.90 "北京" 121.47 31.23 "上海" 113.26 23.13 "广州"
(integer) 3
# 计算两地距离
127.0.0.1:6379> geodist cities 北京 上海 km
"1067.5980"
# 找出某坐标 1500km 半径内的城市,按距离排序
127.0.0.1:6379> geosearch cities frommember 北京 byradius 1500 km asc
1) "北京"
2) "上海"
适用场景:附近的人、附近的门店、外卖骑手就近派单。
4. Stream(流):更专业的消息队列
上一章说过 List 做消息队列的短板:消息取走即删、没有确认机制、不支持多个消费组各消费一份。Stream 是 Redis 5.0 推出的正经消息队列,具备:
- 消息持久化,有唯一递增 ID
- 消费组:多个组各自独立消费全量消息;组内多个消费者分摊消息
- ACK 确认:处理完才确认,消费者崩溃后消息可被重新领取
# 生产消息(* 表示自动生成消息 ID)
127.0.0.1:6379> xadd orders * product "iPhone" qty 2
"1753500000000-0"
# 查看消息
127.0.0.1:6379> xrange orders - +
1) 1) "1753500000000-0"
2) 1) "product"
2) "iPhone"
3) "qty"
4) "2"
# 消费组模式(了解即可):
# xgroup create orders mygroup 0 创建消费组
# xreadgroup group mygroup consumer1 count 1 streams orders > 组内消费
# xack orders mygroup 消息ID 确认处理完成
怎么选:学习/简单场景用 List 就够;需要可靠性但不想引入新组件用 Stream;大型系统的核心链路建议用专业消息队列(Kafka / RabbitMQ / RocketMQ)。
5. 一张总表
| 类型 | 一句话定位 | 代表场景 |
|---|---|---|
| Bitmap | 亿级"是/否"标记,1 人 1 bit | 签到、在线状态 |
| HyperLogLog | 亿级去重计数,恒定 12KB,有 0.81% 误差 | UV 统计 |
| GEO | 经纬度存储与距离计算 | 附近的人/店 |
| Stream | 带消费组和 ACK 的消息队列 | 可靠消息传递 |
💡 新手阶段的正确姿势:记住这张表就够了。真实项目遇到对应场景时,你能想起"Redis 有个现成的东西能干这个",再回来查命令。
6. 动手练习
- 用 Bitmap 模拟自己本周的签到(周一到周三签到,周四没签),统计签到天数
- 用 HyperLogLog 添加 10 个访客(其中 3 个重复),看
pfcount结果 - 用 GEO 添加你所在城市和邻近城市的坐标,算一下距离
数据类型篇完结!接下来深入 Redis 的核心机制 👉 01 过期时间与内存淘汰