如何用 Redis 统计海量 UV?

引言:在当今数字化时代,对于网站和应用程序的运营者而言,了解其用户的行为和习惯是至关重要的。其中,衡量页面的独立访客数量(UV)是评估网站流量和用户参与度的重要指标之一。然而,当面对海量访问数据时,传统的计数方法可能变得低效且成本高昂。为解决这一挑战,Redis 提供了一种高效的解决方案:HyperLogLog。HyperLogLog 是一种基数估算算法,能够在常量时间内对集合中不同元素的近似数量进行快速估算。本文就来详细介绍下如何使用 Redis 统计海量 UV。

PV、UV 是什么?

PV(Page Views)是页面浏览量,指的是网站或应用程序页面被访问的次数。每一次页面的加载都被视为一个页面浏览量,无论是否为同一用户。

UV(Unique Visitors)是独立访客数量,指的是访问网站或应用程序的唯一用户数量。UV通常用于衡量网站或应用程序的独立用户群体规模,而不考虑他们的访问频率。PV 和 UV 是衡量网站或应用程序流量和用户参与度的重要指标之一。

Redis 的 HyperLogLog

请添加图片描述
在 Redis 中,有一种可以用于网页 UV 、PV等值统计的数据结构,这个数据结构就是 HyperLogLog。

HyperLogLog 是一种基数估算算法,可以用于快速计算一个集合中的不同元素数量的近似值。

在使用 HyperLogLog 统计页面 UV 时,我们可以将每个访问者的 IP 地址作为一个元素加入到 HyperLogLog 中,然后通过计算 HyperLogLog 中元素数量的近似值来估计页面的唯一访问者数量。

以下是一个示例代码,展示如何使用 Redis 的 HyperLogLog 实现页面 UV 统计:

import redis.clients.jedis.Jedis;

public class HyperLogLogExample {
    public static void main(String[] args) {
        // 连接 Redis 服务器
        Jedis jedis = new Jedis("localhost");

        // 创建一个 HyperLogLog 实例
        String hyperLogLogKey = "unique_users";
        
        // 模拟用户访问行为,向 HyperLogLog 中添加元素
        jedis.pfadd(hyperLogLogKey, "user1", "user2", "user3", "user4");

        // 获取 HyperLogLog 的基数估计结果
        long estimatedCount = jedis.pfcount(hyperLogLogKey);
        System.out.println("Estimated unique users: " + estimatedCount);

        // 模拟新的用户访问
        jedis.pfadd(hyperLogLogKey, "user5", "user6", "user7");

        // 更新基数估计结果
        estimatedCount = jedis.pfcount(hyperLogLogKey);
        System.out.println("Updated estimated unique users: " + estimatedCount);

        // 关闭 Redis 连接
        jedis.close();
    }
}

在上面的示例代码中,我们使用 Redis 的 pfadd() 方法将每个访问者的 IP 地址加入到名为 page_views 的 HyperLogLog 中。然后,我们使用 pfcount() 方法获取 page_views 中元素数量的近似值,并将其作为页面 UV 的估计值输出到控制台。

工作原理详解

1)HyperLogLog 使用哈希函数将元素映射到位数组中的位置。这个哈希函数具有以下特性

1.1)映射结果均匀分布,确保元素被均匀地分散在位数组中。

1.2)映射结果的位数远远超过位数组的大小,以减少哈希冲突的可能性。

2)位数组存储

当一个元素被哈希映射到位数组中时,位数组的对应位置被设置为 1。但是,HyperLogLog 不仅仅是简单地存储元素是否存在,而是根据哈希函数的结果,找到最高位为 0 的位置,将其后的连续 0 的个数记录下来。这个数值被称为前缀零的数量(Prefix Zeros)。在位数组中,前缀零的数量表示了元素的分布情况,它越大,表示元素的分布越稀疏,因此估计的基数(集合中不同元素的数量)也就越大。

3)估计基数

通过统计位数组中前缀零的数量,并结合适当的校正和插值算法,HyperLogLog 可以估计出集合中不同元素的数量。这个估计值通常是一个近似值,但在大多数情况下是相当准确的。

HyperLogLog 其他应用

1)分布式系统中的基数合并:

在分布式系统中,当多个节点收集数据后需要合并统计结果时,HyperLogLog 可以用于快速、高效地合并基数估计结果。通过将每个节点的 HyperLogLog 结果进行合并,系统可以快速得出整体的基数估计结果,而无需传输大量的原始数据。

2)数据库查询优化:

在数据库系统中,HyperLogLog 可以用于优化查询执行计划,例如对于 DISTINCT 查询或 GROUP BY 查询,可以使用 HyperLogLog 进行基数估计来避免耗时的全表扫描操作,从而提高查询性能。

3)物联网设备管理:

在物联网领域,HyperLogLog 可以用于估计不同设备的数量,帮助企业管理和监控物联网设备的分布和使用情况,从而进行资源调配和性能优化。

HyperLogLog 的优点:

内存效率高:HyperLogLog 使用固定大小的数据结构来估计大数据集的基数,因此在存储方面非常高效。相比之下,传统的统计方法可能需要存储每个计数的详细信息,占用更多的内存空间。

计算效率高:HyperLogLog 在计算基数估计时具有常量时间复杂度,与集合大小无关。这意味着无论数据规模多大,计算基数估计的时间都是固定的。相比之下,传统的统计方法可能需要对整个数据集进行遍历或聚合,时间复杂度可能与数据规模成线性关系。

分布式计算支持:HyperLogLog 可以很容易地在分布式环境下进行计算,各个节点可以独立地计算本地数据的基数估计结果,然后将结果合并。这使得它非常适合处理大规模分布式系统中的基数估计问题。

近似精度可控:HyperLogLog 允许用户在存储和计算效率之间进行权衡,通过调整哈希函数数量或位数,可以控制基数估计结果的近似精度。这使得它可以灵活地应对不同精度要求的场景。

HyperLogLog 的缺点:

近似精度:HyperLogLog 提供的基数估计结果是近似值,而不是精确值。虽然在大多数情况下,它的近似精度可以满足需求,但在一些特定情况下可能无法提供足够精确的结果。

不适用于小数据集:HyperLogLog 在处理小数据集时可能会产生较大的误差,因为在数据量较小时,哈希冲突的概率会增加,从而影响基数估计的准确性。

传统统计方法的缺点:

内存和计算成本高:传统的统计方法可能需要大量的内存来存储详细的计数信息,也可能需要耗费大量的计算资源来对数据集进行聚合或遍历,特别是在大数据集的情况下。

不适用于分布式环境:一些传统的统计方法可能不太适用于分布式环境下的计算,需要额外的复杂性来进行并行化或分布式处理。

综上所述,HyperLogLog 在处理大数据集的基数估计问题时具有显著的优势,尤其在内存和计算效率方面,但在精确性和适用性方面可能存在一些限制。在实际应用中,需要根据具体场景的需求来选择合适的统计方法。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/654284.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

[算法][数字][leetcode]2769.找出最大的可达成数字

题目地址 https://leetcode.cn/problems/find-the-maximum-achievable-number/description/ 题目描述 实现代码 class Solution {public int theMaximumAchievableX(int num, int t) {return num2*t;} }

JavaWeb Servelt原理

Servlet简介: Servlet的主要工作:处理客户端请求,生成动态响应,通常用于扩展基于HTTP协议的Web服务器。 Servlet技术是Java EE规范的组成部分,代表了服务器端的Java程序,主要负责处理来自客户端的Web请求,…

LVM和配额管理

文章目录 一、LVM1.1 LVM概述1.2 LVM的管理命令1.3 创建LVM的过程第一步:先创建物理卷第二步:创建逻辑卷组 / 扩容第三步:创建逻辑卷 / 扩容对ext4文件系统的管理 1.4 删除LVM 二、磁盘配额2.1 磁盘配额概述2.2 磁盘配额命令2.3 磁盘配额设置…

Android 逆向学习【2】——APK基本结构

APK安装在安卓机器上的,相当于就是windows的exe文件 APK实际上是个压缩包 只要是压缩的东西 .jar也是压缩包 里面是.class(java编译后的一些东西) APK是Android Package的缩写,即Android安装包。而apk文件其实就是一个压缩包,我们可以将apk文件的后…

AI预测福彩3D采取888=3策略+和值012路一缩定乾坤测试5月28日预测第4弹

昨天的第二套方案已命中,第一套方案由于杀了对子,导致最终出错。 今天继续基于8883的大底,使用尽可能少的条件进行缩号,同时,同样准备两套方案,一套是我自己的条件进行缩号,另外一套是8883的大底…

工业制造企业为什么要进行数字化转型

人人都在谈数字化转型,政府谈数字化策略方针,企业谈数字化转型方案,员工谈数字化提效工具。互联网企业在谈,工业企业也在谈。 在这种大趋势下,作为一个从事TOB行业十年的老兵,今天就来给大家讲讲&#xff…

ubuntu openvoice部署过程记录,解决python3 -m unidic download 时 unidic无法下载的问题

github给的安装顺序: conda create -n openvoice python3.9 conda activate openvoice git clone gitgithub.com:myshell-ai/OpenVoice.git cd OpenVoice pip install -e .安装MeloTTS: pip install githttps://github.com/myshell-ai/MeloTTS.git python -m unid…

Follow Your Pose: Pose-Guided Text-to-Video Generation using Pose-Free Videos

清华深&港科&深先进&Tencent AAAI24https://github.com/mayuelala/FollowYourPose 问题引入 本文的任务是根据文本来生成高质量的角色视频,并且可以通过pose来控制任务的姿势;当前缺少video-pose caption数据集,所以提出一个两…

【ARM+Codesys案例】T3/RK3568/树莓派+Codesys枕式包装机运动控制器

枕式包装机是一种包装能力非常强,且能适合多种规格用于食品和非食品包装的连续式包装机。它不但能用于无商标包装材料的包装,而且能够使用预先印有商标图案的卷筒材料进行高速包装。同时,具有稳定性高、生产效率高,适合连续包装、…

[图解]伪创新并不宣传自己简单易学

1 00:00:00,450 --> 00:00:04,790 今天这个题目,主要是解答一道 2 00:00:05,580 --> 00:00:07,490 前一阵出过的竞赛题 3 00:00:11,700 --> 00:00:15,170 因为这道题导致我们很多人做错了 4 00:00:15,600 --> 00:00:21,690 然后竞赛的轮次一直没有能…

C++学习日记 | LAB 6 static library 静态库

资料来源:南科大 余仕琪 C/C Program Design LINK:CPP/week06 at main ShiqiYu/CPP GitHub 一、本节内容 本节主要介绍静态库和动态库。 1.1 静态库和动态库的概念 静态链接和静态库(也称为存档)是链接器将所有使用的库函数复制到可执行文件的结果。静…

存内计算从浮点运算优化对数据经济的提升

本篇文章将介绍存内计算技术对于数据经济的提升,我们将从提出问题、解答问题与阐述应用三个方面进行展开介绍,并引入浮点存算、等新兴存算技术进行简要介绍。 一.数据经济&存内计算,结合是否可行? 数据经济与存内计算&#…

恭喜社区迎来新PMC成员!

恭喜Apache SeaTunnel社区又迎来一位PMC Memberliugddx!在社区持续活跃的两年间,大家经常看到这位开源爱好者出现在社区的各种活动中,为项目和社区发展添砖加瓦。如今成为项目PMC Member,意味着在社区中的责任更重了,他…

Github Page 部署失败

添加 .gitmodules 文件 [submodule "themes/ayer"]path themes/ayerurl https://github.com/Shen-Yu/hexo-theme-ayer.git 添加 .nojekyll 文件

文心一言 VS 讯飞星火 VS chatgpt (269)-- 算法导论20.2 4题

四、修改 proto-vEB 结构,以支持重复关键字。如果要写代码,请用go语言。 文心一言: 在原始的 van Emde Boas 树(vEB tree)结构中,关键字(key)是唯一的,不允许有重复的关…

.NET 轻量级、高效任务调度器:ScheduleTask

前言 至于任务调度这个基础功能,重要性不言而喻,大多数业务系统都会用到,世面上有很多成熟的三方库比如Quartz,Hangfire,Coravel 这里我们不讨论三方的库如何使用 而是从0开始自己制作一个简易的任务调度,如果只是到分钟级别的粒…

centos7防火墙入站白名单配置

firewall-cmd --set-default-zonedropfirewall-cmd --get-active-zone记录下当前激活网卡firewall-cmd --permanent --change-interfaceens33 --zonedrop firewall-cmd --zonedrop --list-all 添加信任的源IP和开放端口 firewall-cmd --permanent --add-source192.168.254.1 -…

pikachu—exec“eval“

这是原画面 然后呢? 我们知道会传入到后台rce_eval.php来处理然后通过 eval()是啥? 在eval括号里面可以执行外来机器的命令 然后我们通过php的一个内置的命令 我们通过phpinfo(); 这是输入后的结果

华为机考入门python3--(26)牛客26-字符串排序

分类:字符串 知识点: 字符串是否仅由字母构成 my_str.isalpha() 字母列表按小写排序 letters.sort(keylambda x: x.lower()) 题目来自【牛客】 def custom_sort(input_str):letters []non_letters []for char in input_str:if char.isalpha…

打工人都在偷偷做的副业项目—steam搬砖

steam搬砖其实是一个非常老牌的项目了,之前只有玩游戏玩市场的人知道,其他普通人都不知道。 我们陪跑这个项目不是说这个项目不行了,再拿出来割韭菜,现在依然可以做,我们本身就是项目和培训一比一在做,这一…