首页/数据/数据库速查/去重与 UV 统计选型(Set / HyperLogLog)
Redis 命令96 条

去重与 UV 统计选型(Set / HyperLogLog)

Set 精确去重但内存随基数线性增长;HyperLogLog 固定约 12KB、误差 0.81%,适合海量 UV;两者都支持合并。

数据库速查数据更新于 2026-10-13

精确去重与近似去重

统计独立访客这类去重需求有两条路线:Set 精确记录每个成员,内存随基数线性增长;HyperLogLog 用固定约 12KB 的空间做概率估算,标准误差约 0.81%。选择依据不是哪个更先进,而是业务能否接受误差,以及是否需要在事后列出具体成员。

基本信息

适用平台Redis 2.8.9+ 支持 HyperLogLog
Set 命令SADD、SCARD、SUNIONSTORE
HLL 命令PFADD、PFCOUNT、PFMERGE
HLL 空间每键不超过约 12KB(小基数用稀疏编码更省)
HLL 误差标准误差约 0.81%

典型使用场景

  • 日活、周活、月活统计:基数大且只关心数字,适合 HLL
  • 需要列出具体用户名单的场景:抽奖名单、白名单校验,必须用 Set
  • 多天数据合并出周期去重值:HLL 的 PFMERGE 比多个 Set 求并集省得多
  • 精确对账场景:金额相关的去重统计不能用近似值
  • 接口级去重与限流:Set 可以直接判断成员是否存在

精确与近似两种写法

精确与近似两种写法
# 精确:集合成员可列举,内存随基数增长
SADD uv:day:20261012 uid1 uid2 uid3
SISMEMBER uv:day:20261012 uid2       # 1:可判断成员是否存在
SCARD uv:day:20261012                # 3:精确计数
# 近似:固定空间,只给数字
PFADD hll:uv:20261012 uid1 uid2 uid3
PFCOUNT hll:uv:20261012              # 约 3
# 合并多天得到一个周期去重值
PFMERGE hll:uv:week hll:uv:20261011 hll:uv:20261012
PFCOUNT hll:uv:week
# Set 的合并需要显式生成结果键
SUNIONSTORE uv:week 3 uv:day:20261011 uv:day:20261012

选型对照

维度SetHyperLogLog
精确性精确约 0.81% 标准误差
内存占用随基数线性增长每键固定约 12KB 上限
能否列出成员可以不能,只能给基数
能否判断元素存在可以(SISMEMBER)不能
合并方式SUNIONSTOREPFMERGE
删除单个元素可以(SREM)不支持
小基数用 HLL 反而更贵:稀疏编码虽省空间,但固定开销仍高于几个成员的 Set,量级没上来之前用 Set 更直观。
HLL 不支持删除单个元素:一旦需要「移除某个用户」就必须整键重算,因此它对数据修正类需求很不友好,选型前先确认是否有删改诉求。
PFCOUNT 同时传入多个键时会先做内部临时合并再计数,开销高于单键查询:周期性报表建议先用 PFMERGE 落一个汇总键,日常查询只读这个汇总键,避免每次报表都重新合并。

易错点

  • 拿 HLL 结果对外汇报精确值:估算存在约 0.81% 的固有误差,与明细系统对账时会被质疑数据不一致
  • 小基数场景也用 HLL:固定开销高于等价 Set,得不偿失
  • 用 HLL 做需要列举成员的功能:无法枚举成员,抽奖、白名单这类需求只能换 Set
  • 需要修正历史数据时才发现 HLL 不能删元素:只能整键重算,补救成本高

数据来源与参考

  • Redis 官方文档: HyperLogLog
  • Redis 官方文档: SCARD

相关工具

​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌