Redis 命令及数据类型 -- Hyperloglog
摘要
- 本文介绍 Redis Hyperloglog 数据类型
- 本文基于
redis-7.4.7,springboot-3.5.8 - Redis官网:https://redis.io/
- Redis 命令文档:https://redis.io/docs/latest/commands/
Hyperloglog 数据类型
-
Redis HyperLogLog 是专门用于做基数统计的高级数据类型,核心优势是用极小的内存(固定约
12KB)就能统计海量数据的基数,误差率仅0.81%,无需存储全部数据本身。
基数:指集合中不重复元素的数量(比如统计 UV,就是不重复访客的数量)。
-
Redis Hyperloglog 并非独立数据类型,而是基于 String 类型的位操作扩展
核心使用方式(3个核心命令)
-
HyperLogLog 命令极简,只有 3 个核心操作
PFADD
-
向 HyperLogLog 中添加1个或多个元素,成功添加(元素未存在)返回1,否则返回0。
1 | PFADD key [element [element ...]] |
PFCOUNT
-
统计单个/多个 HyperLogLog 的基数(去重总数),多 key 传入时会计算所有 key 的并集基数。
1 | PFCOUNT key [key ...] |
PFMERGE
-
将多个源 HyperLogLog 合并为1个目标 HyperLogLog,适用于跨维度汇总统计(比如合并今日、昨日的 UV 得到两日总 UV)。
1 | PFMERGE destkey [sourcekey [sourcekey ...]] |
实操示例
示例1:单 key 基础统计(统计网站 UV)
1 | # 1. 模拟3个访客访问,其中用户A重复访问 |
示例2: 多 key 合并与汇总统计
1 | # 1. 分别统计12.17和12.18的UV |
核心应用场景(精准落地场景)
-
HyperLogLog 只关注 “去重数量”,不关注“具体元素是谁”,适合以下高频场景,也是企业级常用方案:
-
网站/APP UV 统计:替代传统的 Set 存储(Set 存海量 UV 内存占用极高),单 key 仅 12KB,轻松统计百万/千万级 UV。
-
业务场景去重计数:比如统计单日/单月的独立支付用户数、独立下单用户数、独立点击商品的用户数。
-
海量数据去重统计:比如统计某接口的独立调用 IP 数、某直播间的独立观看人数、某广告的独立曝光数。
-
跨维度汇总统计:比如合并不同渠道(APP、小程序、H5)的独立访客数,得到全渠道总访客数。
关键注意事项(避坑重点)
-
不存储具体元素,仅存统计结果:无法像 Set 那样获取集合中的具体元素(比如无法通过 HyperLogLog 查到具体是哪些用户访问了网站),只关心“有多少个”,不关心“是谁”。
-
误差不可避免,可控不影响大部分场景:固定误差率
0.81%,数据量越大误差越稳定,UV、独立用户数等场景对精度要求不高,完全够用;若需 100% 精准(比如统计核心交易用户数),需用 Set 或 Hash 实现。 -
内存占用固定,与数据量无关:无论统计 10 个还是 1 亿个元素,单个 HyperLogLog 占用内存约
12KB,这是其核心优势,也是区别于 Set 的关键。 -
元素支持字符串类型:PFADD 传入的元素必须是字符串/字节类型,不支持其他数据类型(如数字、列表等,需手动转为字符串)。
-
过期时间支持:HyperLogLog 本身不自带过期机制,但可通过
EXPIRE key seconds给其设置过期时间(比如 UV 统计按日过期,避免内存堆积)。 -
PFADD 幂等性:重复添加同一元素,不会改变基数结果,也不会额外占用内存,可放心重复调用。
与 Set 统计基数的对比(选型参考)
| 对比维度 | HyperLogLog | Set |
|---|---|---|
| 数据结构类型 | 基数统计结构 | 无序集合 |
| 内存占用 | 固定约 12KB,与数据量无关 | 随元素数量线性增长,海量数据内存占用极高 |
| 统计结果精度 | 非精准,标准误差约 0.81% | 100% 精准 |
| 是否支持获取具体元素 | 不支持 | 支持(如 SMEMBERS) |
| 是否支持去重 | 支持(基数去重) | 支持(元素级去重) |
| 统计性能 | 极快(固定计算逻辑,O(1)) | 数据量越大,统计与遍历成本越高 |
| 适合数据规模 | 超大规模(百万 / 千万 / 亿级) | 中小规模集合 |
| 常见使用场景 | UV / DAU 统计、独立 IP 数、访问用户数 | 好友列表、标签集合、关注列表 |
| 是否可做集合运算 | 不支持 | 支持(SUNION / SINTER / SDIFF) |
| 是否可序列化/持久化 | 可(Redis 内部结构) | 可 |
| 选型结论 | 低成本 + 海量数据 + 可接受误差的基数统计 | 精准统计 + 需要元素明细的场景 |
HyperLogLog 命令
-
SpringBoot 的
StringRedisTemplate.opsForHyperLogLog()中 HyperLogLog 数据类型 的操作方法与 Redis 原生命令的对应关系如下:
注意这里一定要用
StringRedisTemplate来操作 HyperLogLog
| 方法功能 | 方法 | Redis 原始命令 | 备注 / 使用建议 |
|---|---|---|---|
| 添加元素 | Long add(K key, V... values) |
PFADD key element [element ...] |
返回 1 表示 HLL 结构发生变化 |
| 获取基数(去重数) | Long size(K... keys) |
PFCOUNT key [key ...] |
支持多 key 合并统计 |
| 合并 HLL | Long union(K destination, K... sourceKeys) |
PFMERGE destkey sourcekey [sourcekey ...] |
合并后写入 destkey |
| 删除 HLL | void delete(K key) |
DEL key |
直接删除整个 HLL |