0

0

Redis数据类型学习之HyperLogLog浅析

青灯夜游

青灯夜游

发布时间:2022-01-21 10:00:59

|

2732人浏览过

|

来源于掘金社区

转载

本篇文章带大家了解一下redis数据类型中的hyperloglog,通常用来统计一个集合中不重复的元素个数,希望对大家有所帮助!

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,它既可以实现产品的需求还占用更少的内存。【相关推荐:Redis视频教程

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。

例如:

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

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

SERCMS游戏币交易系统
SERCMS游戏币交易系统

这套系统是之前为一个朋友开发的一套游戏币交易系统,开发语言asp+javascript 数据库是Access。现在提供免费下载给新人学习,请不要用于商业用处。大分类为:商品管理现金转虚拟币管理 虚拟币转现金管理 历史转换记录 ID搜索虚拟币管理用户管理前台用户管理 被停权的会员 后台管理员添加 后台用户员管理 数据表备份分类管理游戏名称管理 服务器名管理数据统计查询交易类型数据信息管理修改重要公告

下载

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 的特性十分适合:计数(月度、年度统计)、去重(垃圾短信检测)等场景。

更多编程相关知识,请访问:编程入门!!

相关专题

更多
数据类型有哪几种
数据类型有哪几种

数据类型有整型、浮点型、字符型、字符串型、布尔型、数组、结构体和枚举等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

298

2023.10.31

php数据类型
php数据类型

本专题整合了php数据类型相关内容,阅读专题下面的文章了解更多详细内容。

216

2025.10.31

treenode的用法
treenode的用法

​在计算机编程领域,TreeNode是一种常见的数据结构,通常用于构建树形结构。在不同的编程语言中,TreeNode可能有不同的实现方式和用法,通常用于表示树的节点信息。更多关于treenode相关问题详情请看本专题下面的文章。php中文网欢迎大家前来学习。

529

2023.12.01

C++ 高效算法与数据结构
C++ 高效算法与数据结构

本专题讲解 C++ 中常用算法与数据结构的实现与优化,涵盖排序算法(快速排序、归并排序)、查找算法、图算法、动态规划、贪心算法等,并结合实际案例分析如何选择最优算法来提高程序效率。通过深入理解数据结构(链表、树、堆、哈希表等),帮助开发者提升 在复杂应用中的算法设计与性能优化能力。

12

2025.12.22

页面置换算法
页面置换算法

页面置换算法是操作系统中用来决定在内存中哪些页面应该被换出以便为新的页面提供空间的算法。本专题为大家提供页面置换算法的相关文章,大家可以免费体验。

389

2023.08.14

常用的数据库软件
常用的数据库软件

常用的数据库软件有MySQL、Oracle、SQL Server、PostgreSQL、MongoDB、Redis、Cassandra、Hadoop、Spark和Amazon DynamoDB。更多关于数据库软件的内容详情请看本专题下面的文章。php中文网欢迎大家前来学习。

957

2023.11.02

内存数据库有哪些
内存数据库有哪些

内存数据库有Redis、Memcached、Apache Ignite、VoltDB、TimesTen、H2 Database、Aerospike、Oracle TimesTen In-Memory Database、SAP HANA和ache Cassandra。更多关于内存数据库相关问题,详情请看本专题下面的文章。php中文网欢迎大家前来学习。

621

2023.11.14

mongodb和redis哪个读取速度快
mongodb和redis哪个读取速度快

redis 的读取速度比 mongodb 更快。原因包括:1. redis 使用简单的键值存储,而 mongodb 存储 json 格式的数据,需要解析和反序列化。2. redis 使用哈希表快速查找数据,而 mongodb 使用 b-tree 索引。因此,redis 在需要高性能读取操作的应用程序中是一个更好的选择。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

472

2024.04.02

php源码安装教程大全
php源码安装教程大全

本专题整合了php源码安装教程,阅读专题下面的文章了解更多详细内容。

74

2025.12.31

热门下载

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

精品课程

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

共6课时 | 0.3万人学习

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

共72课时 | 6.2万人学习

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

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