如何借助Redis更高效统计UV?——Hyperloglog篇

本文涉及的产品
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
云数据库 Tair(兼容Redis),内存型 2GB
简介: Redis的HyperLogLog数据类型是用于近似计算大规模数据集中不重复元素基数的工具,它以低空间开销(约12KB)提供高精度的估算(误差率约0.81%)。通过`pfadd`添加元素,`pfcount`统计数量,`pfmerge`合并多个HyperLogLog,实现去重计数。尽管内部存储为字符串,但它是概率数据结构,适合高效UV统计和其他大数据场景。

在今天的互联网时代,数据如潮水般汹涌而来。从用户行为数据、系统日志到实时交互数据,如何高效、准确地统计这海量数据中的唯一元素数量,成为了一个不小的挑战。

今天,我们要一起探索的是 Redis 中一个非常强大但可能被忽视的数据类型——HyperLogLog,它如何在牺牲极少的准确度前提下,实现对大规模数据集的快速去重计数。

什么是 HyperLogLog?

HyperLogLog 是一种用于基数统计的算法,基数指的是一个集合中不重复元素的数量

想象一下,当我们面对数亿级别的数据时,传统的去重统计方法不仅计算量大,而且消耗大量的存储空间。HyperLogLog 则以一种非常节省空间的方式,解决了这个问题,虽然它的计算结果是一个估计值,但是准确率非常高,通常误差率仅为 0.81%

使用 Redis 的 HyperLogLog 实现去重计数

添加元素:pfadd

首先,我们看一下如何向 HyperLogLog 中添加元素。Redis 提供了 pfadd 命令用于添加元素到 HyperLogLog 中。

127.0.0.1:6379> pfadd p1 a b c d e f g
(integer) 1

这里,我们添加了七个元素(a, b, c, d, e, f, g)到 HyperLogLog p1 中。返回值 (integer) 1 表示操作成功。

统计元素数量:pfcount

接下来,我们利用 pfcount 命令来获取 HyperLogLog 中的元素个数。

127.0.0.1:6379> pfcount p1
(integer) 7

通过 pfcount p1,我们得知 HyperLogLog p1 中有七个唯一元素,和我们之前添加的元素数量一致。

合并 HyperLogLog:pfmerge

如果我们有多个 HyperLogLog,想要合并它们的统计结果,该怎么做呢?Redis 的 pfmerge 命令能够帮助我们实现这一点。

127.0.0.1:6379> pfadd p2 d e f g h i j k
(integer) 1
127.0.0.1:6379> pfcount p2
(integer) 8

127.0.0.1:6379> pfmerge p3 p1 p2
OK

127.0.0.1:6379> pfcount p3
(integer) 11

从以上例子中,我们可以看到 pfadd 命令分别向 p1 和 p2 中添加了不同的元素。通过 pfmerge p3 p1 p2,我们将 p1 和 p2 合并到了 p3 中,并用 pfcount p3 确认了合并后 HyperLogLog p3 中共有 11 个唯一元素。

添加相同元素时

值得一提的是,如果我们尝试再次添加相同的元素到 HyperLogLog,它将不会增加计数,因为 HyperLogLog 本质上是一种去重计数工具。

刚刚我们往 p1 中添加了 (a, b, c, d, e, f, g) 七个元素,那么如果此时我们添加几个相同的元素以及少量的不同元素,会怎样呢?

127.0.0.1:6379> pfadd p1 a a b c h
(integer) 1
127.0.0.1:6379> pfcount p1
(integer) 8
127.0.0.1:6379>

我们可以看到,p1 只会统计不同的元素的个数,会自动过滤掉相同的元素。依据这个特性,是不是在脑海中就里面想到了一个常见的应用场景了?是的,依据这个去重特性,我们可以非常方便的做 UV 统计。

UV(Unique visitor):是指通过互联网访问、浏览这个网页的自然人。访问的一个电脑客户端为一个访客,一天内同一个访客仅被计算一次。

传统的做法是使用 set 保存用户的 ID,然后统计 set 中元素的数量作为判断标准。但是这种方式保存了大量的用户 ID,用户 ID 一般比较长,这就占用空间,还很麻烦。我们的目的是计数,不是保存数据,所以这样做有弊端。但是如果使用 hyperloglog 就比较合适了。

hyperloglog 的优点是占用内存小,并且是固定的。存储 2^64 个不同元素的基数,只需要 12 KB 的空间。

数据类型:type

最后,我们来确认一下 HyperLogLog 的数据类型。

127.0.0.1:6379> type p1
string

虽然 type p1 返回的是 string,但在 Redis 中,HyperLogLog 是作为一种概率型数据结构实现的,它通过一种特殊的字符串格式来存储数据。因此,虽然它在 Redis 中表现为字符串类型,但它用于实现基数统计的功能。

小结

HyperLogLog 提供了一种非常高效的方式来对大规模数据集进行去重计数。虽然其结果是估计值,但其高效性和准确度使其在处理大数据统计时表现出色。

通过上述的简单示例,相信你已经对 Redis 的 HyperLogLog 有了基本的了解。无论是实时数据分析、日志统计还是用户行为分析,HyperLogLog 都是一个值得尝试的利器。

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
4月前
|
存储 NoSQL Java
Redis助力高并发网站:在线用户统计不再是难题!
小米带你了解如何使用Redis高效统计网站的在线与并发用户数。通过维护用户的活跃时间,利用Redis有序集合(Sorted Set)特性,可实时更新在线用户列表并统计数量。具体实现包括记录用户上线时间、定期清理离线用户及统计特定时间窗口内的活跃用户数。这种方法适用于高并发场景,保证统计结果的实时性和准确性。跟着小米一起探索Redis的强大功能吧!
102 2
|
1月前
|
NoSQL Java API
springboot项目Redis统计在线用户
通过本文的介绍,您可以在Spring Boot项目中使用Redis实现在线用户统计。通过合理配置Redis和实现用户登录、注销及统计逻辑,您可以高效地管理在线用户。希望本文的详细解释和代码示例能帮助您在实际项目中成功应用这一技术。
32 4
|
2月前
|
NoSQL 算法 关系型数据库
Redis HyperLogLog
10月更文挑战第17天
32 2
|
6月前
|
存储 NoSQL 算法
Redis系列学习文章分享---第十篇(Redis快速入门之附近商铺+用户签到+UV统计)
Redis系列学习文章分享---第十篇(Redis快速入门之附近商铺+用户签到+UV统计)
44 0
|
4月前
|
存储 监控 NoSQL
redis数据结构-HyperLogLog
redis数据结构-HyperLogLog
46 1
|
5月前
|
NoSQL Redis C++
c++开发redis module问题之在复杂的Redis模块中,特别是使用第三方库或C++开发时,接管内存统计有哪些困难
c++开发redis module问题之在复杂的Redis模块中,特别是使用第三方库或C++开发时,接管内存统计有哪些困难
|
4月前
|
NoSQL Java Redis
Redis字符串数据类型之INCR命令,通常用于统计网站访问量,文章访问量,实现分布式锁
这篇文章详细解释了Redis的INCR命令,它用于将键的值增加1,通常用于统计网站访问量、文章访问量,以及实现分布式锁,同时提供了Java代码示例和分布式锁的实现思路。
141 0
|
5月前
|
存储 NoSQL 算法
Redis中 HyperLogLog数据类型使用总结
Redis中 HyperLogLog数据类型使用总结
28 0
|
5月前
|
NoSQL Redis
Redis 使用 hyperLogLog 实现请求ip去重的浏览量
Redis 使用 hyperLogLog 实现请求ip去重的浏览量
40 0
|
7月前
|
SQL NoSQL Java
Redis数据类型 Hash Set Zset Bitmap HyperLogLog GEO
Redis数据类型 Hash Set Zset Bitmap HyperLogLog GEO
62 0