0

0

Redis的HyperLogLog算法怎么用

王林

王林

发布时间:2023-05-29 21:49:37

|

1364人浏览过

|

来源于亿速云

转载

redis的hyperloglog算法怎么用

你正在愉快地偷懒,但产品经理却通过邮件向你发送了一份需求文档。公司需要长期统计网站每天的访客IP,统计时间可能会持续数月甚至数年。

你看完需求就觉得这 so easy 啊,使用 Redis 的集合类型可以轻松实现这个功能:每天生成一个集合类型的键,使用 SADD 存储每天的访客 IP,使用 SCARD 命令就可以轻松得到每天访客 IP 的数量。

你很快就敲完了代码并通过测试,这个功能就上线了。上线后运行一段时间发现 Redis 所在服务器开始告警,原因是某些键的内存占用过大,你看了一下发现这些键都是存储访客 IP 的集合键。你这才拍了一下脑袋,知道自己给自己挖了一个大坑。

假设存储一个 IPv4 格式的 IP 地址最多需要 15 个字节,网站每天最多有 100 万个访客访问网站。这些集合键一个月就将使用 0.45 GB 的内存,一年将占用 5.4 GB 的内存,这还只是估算了 IPv4 格式的情况下,若是 IPv6 格式将占用更多的内存。虽然 SADD 和 SCARD 的时间复杂度都是 O(1),但它们在内存消耗上是无法容忍的。

你在 Redis 的官方网站翻了翻,发现 Redis 还提供了一种数据类型 HyperLogLog,它既可以实现产品的需求还占用更少的内存。

HyperLogLog 算法

HyperLogLog 是一个专门为了计算集合的基数而创建的概率算法,它可以计算出一个给定集合的近似基数。

近似基数并非集合的实际基数,它可能会比实际的基数小一点或者大一点,但是估算基数和实际基数之间的误差会处于一个合理的范围之内,对于那些不要求十分精确的统计就可以使用 HyperLogLog 算法。

HyperLogLog 的优点在于它计算近似基数所需的内存并不会因为集合的大小而改变,无论集合包含的元素有多少个,HyperLogLog 进行计算所需的内存总是固定的,并且是非常少的。

Redis 的每个 HyperLogLog 类型只需要使用 12KB 内存空间,就可以对接近:264 个元素进行计数,而算法的标准误差仅为 0.81%。

如果使用 HyperLogLog 类型实现上述功能,每天有 100 万个访客的情况下,1 个月也仅仅占用 360KB 的内存。

PFADD

通过 PFADD 命令可以对给定的一个或多个集合元素进行计数。

PFADD key element [element...]

根据给定的元素是否已经进行过计数,PFADD 命令可能返回 0,也可能返回 1:

  • 如果给定的所有元素都已经进行过计数,那么 PFADD 命令将返回 0,表示 HyperLogLog 计算出的近似基数没有发生变化。

  • 如果给定的元素中出现了至少一个之前没有进行过计数的元素,导致 HyperLogLog 计算出的近似基数发生了变化,那么 PFADD 命令将返回 1。

例如:

音剪
音剪

喜马拉雅旗下的一站式AI音频创作平台,强大的在线剪辑能力,帮你轻松创作优秀的音频作品

下载
redis> PFADD letters a b c -- 第一次添加
(integer) 1
redis> PFADD letters a     -- 第二次添加
(integer) 0

如果在调用该命令时仅指定 key 而不指定元素也是可以的,如果 key 存在,则不会有任何操作,如果不存在,则会创建一个数据结构(返回 1)。

PFCOUNT

使用 PFCOUNT 命令可以获取基于 HyperLogLog 近似计算的集合基数。若给定的 key 不存在将返回 0。

PFCOUNT key [key...]

例如:

redis> PFCOUNT letters
(integer) 3

当向 PFCOUNT 传入多个 HyperLogLog 时,PFCOUNT 命令将先对所有的 HyperLogLog 求并集,然后返回近似基数。

redis> PFADD letters1 a b c
(integer) 1
redis> PFADD letters2 c d e
(integer) 1
redis> PFCOUNT letters1 letters2
(integer) 5

PFMERGE

PFMERGE 命令可以对多个 HyperLogLog 执行并集计算,然后把计算得出的并集 HyperLogLog 保存到指定的键中。

PFMERGE destKey sourceKey [sourceKey...]

如果指定的键已经存在,PFMERGE 命令将覆盖已有的键。

redis> PFADD letters1 a b c
(integer) 1
redis> PFADD letters2 c d e
(integer) 1
redis> PFMERGE res letters1 letters2
OK
redis> PFCOUNT res
(integer) 5

可以看到 PFMERGE 和 PFCOUNT 命令十分相似,实际上 PFCOUNT 命令在计算多个 HyperLogLog 的近似基数时会执行以下操作:

  • 在内部调用 PFMERGE 命令,计算所有给定 HyperLogLog 的并集,并将这个并集存储到一个临时的 HyperLogLog 中。

  • 对临时 HyperLogLog 执行 PFCOUNT 命令,得到它的近似基数。

  • 删除临时 HyperLogLog。

  • 返回得到的近似基数。

当程序需要对多个 HyperLogLog 调用 PFCOUNT 命令,并且这个调用可能会重复执行多次时,可以考虑把这一调用替换成相应的 PFMERGE 命令调用:通过把并集的计算结果存储到指定的 HyperLogLog 中而不是每次都重新计算并集,程序可以最大程度地减少不必要的并集计算。

业务场景

HyperLogLog 的特性十分适合:计数(月度、年度统计)、去重(垃圾短信检测)等场景。

相关专题

更多
PS使用蒙版相关教程
PS使用蒙版相关教程

本专题整合了ps使用蒙版相关教程,阅读专题下面的文章了解更多详细内容。

23

2026.01.19

java用途介绍
java用途介绍

本专题整合了java用途功能相关介绍,阅读专题下面的文章了解更多详细内容。

11

2026.01.19

java输出数组相关教程
java输出数组相关教程

本专题整合了java输出数组相关教程,阅读专题下面的文章了解更多详细内容。

3

2026.01.19

java接口相关教程
java接口相关教程

本专题整合了java接口相关内容,阅读专题下面的文章了解更多详细内容。

2

2026.01.19

xml格式相关教程
xml格式相关教程

本专题整合了xml格式相关教程汇总,阅读专题下面的文章了解更多详细内容。

4

2026.01.19

PHP WebSocket 实时通信开发
PHP WebSocket 实时通信开发

本专题系统讲解 PHP 在实时通信与长连接场景中的应用实践,涵盖 WebSocket 协议原理、服务端连接管理、消息推送机制、心跳检测、断线重连以及与前端的实时交互实现。通过聊天系统、实时通知等案例,帮助开发者掌握 使用 PHP 构建实时通信与推送服务的完整开发流程,适用于即时消息与高互动性应用场景。

13

2026.01.19

微信聊天记录删除恢复导出教程汇总
微信聊天记录删除恢复导出教程汇总

本专题整合了微信聊天记录相关教程大全,阅读专题下面的文章了解更多详细内容。

93

2026.01.18

高德地图升级方法汇总
高德地图升级方法汇总

本专题整合了高德地图升级相关教程,阅读专题下面的文章了解更多详细内容。

112

2026.01.16

全民K歌得高分教程大全
全民K歌得高分教程大全

本专题整合了全民K歌得高分技巧汇总,阅读专题下面的文章了解更多详细内容。

155

2026.01.16

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
进程与SOCKET
进程与SOCKET

共6课时 | 0.3万人学习

Redis+MySQL数据库面试教程
Redis+MySQL数据库面试教程

共72课时 | 6.4万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号