hyperlog的使用
redis中的hyperlog的原理和应用场景
Redis 中的 HyperLogLog(HLL) 是一种用于 基数统计(Cardinality Counting) 的概率数据结构。
它的核心作用是:
统计一个集合中有多少个不同的元素(去重计数),但不保存元素本身。
例如:
- 统计网站 UV(独立访客数)
- 统计游戏每日活跃用户数(DAU)
- 统计某活动参与人数
- 统计某广告曝光用户数
一、为什么需要 HyperLogLog
假设统计一天内访问网站的独立用户:
普通 Set
SADD uv:20260601 user1
SADD uv:20260601 user2
SADD uv:20260601 user3
查询:
SCARD uv:20260601
返回:
3
准确无误。
但是如果:
1亿用户
每个 userId:
8字节
那么:
100000000 × 8
≈ 800MB
实际 Redis Set 还会有哈希表开销:
可能达到几GB
对于:
- DAU
- UV
- 广告用户数
来说:
太浪费内存
二、HyperLogLog 的优势
Redis 的 HyperLogLog:
固定占用约 12KB
无论:
100个元素
100万元素
1亿元素
10亿元素
都是:
≈12KB
这是最大的优势。
三、Redis 命令
添加元素
PFADD uv user1 user2 user3
查询基数
PFCOUNT uv
返回:
3
合并多个 HLL
例如:
PFADD day1 u1 u2 u3
PFADD day2 u2 u3 u4
合并:
PFMERGE total day1 day2
统计:
PFCOUNT total
结果:
4
因为:
u1
u2
u3
u4
共4个不同用户。
四、HyperLogLog 的原理
它不是存储元素。
例如:
user123
不会存进去。
首先计算:
hash(user123)
例如得到:
110001010100010101...
一个 64 位哈希值。
然后观察:
从左到右连续0出现了多少次
例如:
000000101001...
连续:
6个0
统计学规律:
连续0越多
说明样本空间越大
例如:
出现
0000000000001
连续:
12个0
概率:
1/2^12
≈ 1/4096
说明至少已经观察到了几千个不同元素。
HyperLogLog 就是利用:
最大前导零数量
来估算:
基数(去重数量)
五、Redis 如何提高精度
如果只记录:
最大前导零
误差会很大。
Redis 使用:
16384个桶
即:
2^14
个 Register。
例如:
hash(user1)
hash(user2)
hash(user3)
先根据前14位:
决定落在哪个桶
然后每个桶记录:
最大前导零数
最后利用:
调和平均数
进行估算。
误差控制在:
0.81%
Redis 官方给出的标准误差:
±0.81%
六、误差示例
真实数量:
1000000
HyperLogLog:
991200
或
1007300
都属于正常范围。
误差:
约0.81%
七、和 Set 对比
| 对比项 | Set | HyperLogLog |
|---|---|---|
| 去重统计 | √ | √ |
| 保存元素 | √ | × |
| 遍历元素 | √ | × |
| 删除元素 | √ | × |
| 内存 | 很大 | 固定12KB |
| 精度 | 100% | 99.19% |
| 支持交集 | √ | × |
| 支持差集 | √ | × |
八、典型应用场景
网站 UV
统计:
今日独立访客
PFADD uv:20260601 userId
PFCOUNT uv:20260601
游戏 DAU
统计:
今日活跃用户数
PFADD dau:20260601 userId
晚上:
PFCOUNT dau:20260601
广告系统
统计:
广告覆盖人数
PFADD ad:1001 userId
活动参与人数
统计:
618活动参与人数
PFADD event:618 userId
九、不适合的场景
需要精确人数
例如:
银行客户数
财务统计
订单数
余额用户数
不能使用。
因为:
存在误差
需要知道是谁
例如:
有哪些用户参与了活动
HyperLogLog 无法做到。
因为:
只记录统计信息
不保存元素
十、游戏开发中的实际案例
假设你的队长小翼游戏有 500 万玩家。
统计每日活跃:
Set方案
SADD dau:20260601 userId
可能占用:
几百MB
HyperLogLog方案
PFADD dau:20260601 userId
占用:
12KB
统计:
PFCOUNT dau:20260601
得到:
4,983,112
真实可能:
5,000,000
误差不到 1%。
对于运营报表来说通常完全可以接受。
因此:
- DAU
- WAU(周活)
- MAU(月活)
- UV
- 广告覆盖人数
这些场景非常适合 HyperLogLog。
而涉及发奖、结算、风控等需要精确人数的业务,则应该使用 Redis Set 或数据库统计。
浙公网安备 33010602011771号