Bitmap 与 HyperLogLog
约 619 字大约 2 分钟
布欧-Lewyon
2026-05-15
Bitmap
Bitmap 是 String 的位操作视图,用位(bit)表示状态。
# SETBIT:设置某一位(0 或 1)
SETBIT sign:2026-05-15 100 1 # 用户 100 签到
SETBIT sign:2026-05-15 101 1 # 用户 101 签到
# GETBIT:获取某一位
GETBIT sign:2026-05-15 100 # 1
# BITCOUNT:统计 1 的个数(签到人数)
BITCOUNT sign:2026-05-15 # 2
# BITOP:位运算
# 计算月签到记录(5 月 1 日到 15 日签到的用户)
BITOP AND sign:may sign:2026-05-01 sign:2026-05-02 ... sign:2026-05-15
# BITPOS:查找第一个 0 或 1 的位
BITPOS sign:2026-05-15 0 # 第一个未签到的用户位应用场景
# 日活统计(一天的活跃用户)
SETBIT uv:2026-05-15 100 1
SETBIT uv:2026-05-15 101 1
BITCOUNT uv:2026-05-15 # DAU
# 7 天连续活跃
BITOP AND uv:weekly uv:2026-05-09 uv:2026-05-10 ... uv:2026-05-15
BITCOUNT uv:weekly
# 用户签到(用户 ID 作为位偏移)
SETBIT sign:user:100 0 1 # 第 1 天签到
SETBIT sign:user:100 1 0 # 第 2 天未签到
BITCOUNT sign:user:100 # 签到总天数内存计算
# 1 亿用户的日活记录只需要约 12MB
# 100,000,000 / 8 / 1024 / 1024 ≈ 12MBHyperLogLog
HyperLogLog 是一个基数估算数据结构,用于统计不重复元素的数量(UV),有 0.81% 的标准误差。
# PFADD:添加元素
PFADD uv:daily:2026-05-15 "user:100" "user:101" "user:100"
# PFCOUNT:估算基数(不重复数量)
PFCOUNT uv:daily:2026-05-15 # 2
# PFMERGE:合并多个 HyperLogLog
PFMERGE uv:weekly uv:daily:2026-05-09 uv:daily:2026-05-10 ... uv:daily:2026-05-15
PFCOUNT uv:weekly应用场景
# 百万级 UV 统计(12KB 内存即可统计 2^64 个元素)
PFADD uv:page:/home "ip:192.168.1.1"
PFADD uv:page:/home "ip:192.168.1.2"
PFADD uv:page:/home "ip:192.168.1.1"
PFCOUNT uv:page:/home # 2
# 注意:误差约 0.81%数据结构对比
| 功能 | Bitmap | HyperLogLog |
|---|---|---|
| 用途 | 位图状态 | 大基数统计 |
| 精度 | 精确 | 近似(0.81% 误差) |
| 内存 | 约 12MB/亿位 | 固定 12KB |
| 支持去重 | ✅ | ✅ |
| 支持交集 | ✅ BITOP AND | ❌ 不精确 |
小结
- Bitmap:每一位表示一个状态,适合签到、日活等精确场景。
BITCOUNT统计 1 的数量,BITOP做位运算。- HyperLogLog:固定 12KB 内存统计海量 UV,允许 0.81% 误差。
PFADD添加元素,PFCOUNT估算基数,PFMERGE合并。- Bitmap 精确但内存与数据量成正比;HyperLogLog 近似但内存极小。
上一节:Stream 与消息队列进阶 下一节:RDB 与 AOF 持久化
