pfadd+pfcount可12kb内存估算10亿uv,误差±0.81%;pfadd登记哈希特征而非插入,重复id不改变计数;pfcount多key等价pfmerge后估算,误差不叠加;hll不支持反查原始元素。

能用 PFADD + PFCOUNT 就别碰 SET,12KB 内存扛住 10 亿 UV 是真实可行的,前提是接受 ±0.81% 误差。
PFADD 添加元素时,重复值不会改变计数结果
这是去重逻辑的底层保障,PFADD 不是“插入”,而是“登记哈希特征”——同一个用户 ID 多次调用,只会触发一次寄存器更新(如果该哈希对应的桶中前导零数未被超越)。
- 返回值
1表示内部状态可能变化(不等于“新增了唯一值”,只代表估算值有潜在更新);返回0表示所有输入都已被现有哈希分布“覆盖”,估算值不变 - 不要依赖返回值判断“是否首次访问”,它不是原子级存在性检查,
PFADD本身不提供EXISTS语义 - 字符串、数字、二进制数据均可直接传入,Redis 会统一做
MurmurHash3(128 位),无需客户端预哈希
PFCOUNT 统计时,单 key 和多 key 行为完全不同
PFCOUNT key 是对单个 HyperLogLog 结构做估算;PFCOUNT key1 key2 key3 并非分别统计再相加,而是先隐式执行一次 PFMERGE 临时合并,再估算总基数——这正是它支持“跨日 UV 合并”的关键机制。
Redis 8.2.3 是一款安全优先的高性能键值存储系统。该版本紧急修复了可能引发远程代码执行(RCE)的高危漏洞(CVE-2025-62507),并解决了 HyperLogLog 及 Cuckoo Filter 等数据结构在特定场景下的崩溃问题。建议所有用户立即升级,以保障生产环境的系统稳定与数据安全。
- 多 key 调用等价于:新建一个临时 HLL →
PFMERGE所有输入 key →PFCOUNT→ 丢弃临时结构。无持久化开销,但有计算成本 - 如果每天生成一个
uv:20260713,要算周 UV,直接PFCOUNT uv:20260707 uv:20260708 ... uv:20260713即可,不用提前PFMERGE到新 key - 注意:多 key 的误差仍是 ~0.81%,不是误差叠加。合并本身不放大误差,因为底层是调和平均融合寄存器值
PFMERGE 不是“数据搬运”,而是寄存器层面的按位取最大值
两个 PFMERGE 源 key 必须都是合法 HyperLogLog 类型,否则报错 WRONGTYPE Operation against a key holding the wrong kind of value。合并过程不读原始元素,只对比 16384 个桶中各自存储的“最大前导零数”,取每个桶的较大者填入目标 key。
- 合并后目标 key 的内存占用仍是固定 12KB,和源 key 一样,不会翻倍或累加
- 不能用
PFMERGE合并 HLL 和其他类型(如SET或STRING),Redis 会拒绝并报错 - 如果某个源 key 为空(从未
PFADD过),它会被视作全零寄存器数组,不影响合并结果
真正容易被忽略的点在于:HyperLogLog 不支持反向查询——你永远拿不到“有哪些用户被计入了”,它只存摘要,不存原始 ID。如果业务既要 UV 总数,又要抽样分析用户构成,得额外用 SET 或 Sorted Set 做采样,不能指望 HLL 补足这部分能力。










