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 对比

对比项SetHyperLogLog
去重统计
保存元素 ×
遍历元素 ×
删除元素 ×
内存 很大 固定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 或数据库统计。

posted on 2026-07-05 15:04  日思日睿  阅读(16)  评论(0)    收藏  举报