如何用 Redis 统计海量 UV?

news2024/12/22 16:46:08
引言:在当今数字化时代,对于网站和应用程序的运营者而言,了解其用户的行为和习惯是至关重要的。其中,衡量页面的独立访客数量(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 在处理大数据集的基数估计问题时具有显著的优势,尤其在内存和计算效率方面,但在精确性和适用性方面可能存在一些限制。在实际应用中,需要根据具体场景的需求来选择合适的统计方法。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

2024-BurpSuite快速配置Jython插件环境

文章目录 前言一、下载Jython二、配置Python environment 前言 很多插件需要python环境,Burpsuite本身是支持java的,Jython就是java和python的结合。 提示:以下是本篇文章正文内容,下面案例可供参考 一、下载Jython https://ww…

基于Spring+Struts2+Hibernate+MySQL的个人网上银行

## 系统概述该系统采用SpringHibernateStruts2框架搭建,实现了登录、退出功能。不同账号之间进行转账功能,查询转账记录功能,修改登录密码功能。## 使用方法* 将项目导入idea,修改hibernate.cfg.xml中的数据库用户名、密码等信息…

Go 语言简介 -- 高效、简洁与现代化编程的完美结合

在现代软件开发领域,选择合适的编程语言对于项目的成功至关重要。Go 语言(又称 Golang )自 2009 年由Google发布以来,以其简洁的语法、高效的并发模型以及强大的性能,迅速成为开发者们的新宠。Go语言不仅融合了传统编译…

水滴式粉碎机:让破碎多样化

水滴式粉碎机以其新的粉碎技术和卓越的性能,引领着粉碎技术的新革命。它采用了高速旋转技术,通过转子对物料进行撞击和摩擦,实现了对物料的精细粉碎,制备出了高品质、高附加值的产品。 水滴式粉碎机在多个行业中都有着广泛的应用…

让大模型变得更聪明:人工智能的未来发展之路

💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

搞到了阿里云大佬的docker笔记,实战总结一步到位,建议收藏

Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口。 Docker在今天已经算是明星…

git 检查用户是否是gitlab用户

背景: 公司代码要从老的git库迁到新的git库,老git库上部分提交用户在新git库上没有,解决方法: 让gitlab不再检查提交用户是否是gitlab用户。具体操作: 去掉下面的勾选,保存配置即可。

Simulate Ring Resonator in INTERCONNECT

Simulate Ring Resonator in INTERCONNECT 正文正文 首先,我们采用 Interconnect 模块的工作流程 一文中介绍的方法添加一个直波导器件。接着,我们需要对它的名称进行更改,此时我们看左侧 Property View - Root Element 中的 General 属性,我们发现 name 属性是灰色的,无…

安川MC2000机械手CPU单元维修技巧汇总

在工业自动化领域,安川机器人因其高性能和稳定性而备受青睐。然而,即使是可靠的设备也会出现故障。下面将介绍安川MC2000机器人CPU单元维修方法,以便在遇到故障时能够快速恢复机器人的正常运行。安川机器人CPU单元是机器人的“大脑”&#xf…

如何与“病态”的人建立友谊:一种基于理解与接纳的视角

在我们的生活中,我们经常会遇到一些行为举止让我们感到不适或难以理解的人。这些人可能因为他们的某些行为被标签为“病态”,但真的应该如此简单地对他们进行评判吗?本文将探讨如何与被视为“病态”的人建立友谊,以及为什么这种接…

【stm32/CubeMX、HAL库】嵌入式实验六:定时器(2)|PWM输出

参考: 【【正点原子】手把手教你学STM32CubeIDE开发】 https://www.bilibili.com/video/BV1Wp42127Cx/?p13&share_sourcecopy_web&vd_source9332b8fc5ea8d349a54c3989f6189fd3 《嵌入式系统基础与实践》刘黎明等编著,第九章定时器&#xff0c…

MyCat2之分库分表

原理 一个数据库由很多表的构成,每个表对应的不同的业务,垂直切分是指按照业务将表进行分类,分不到不同的数据库上,这样压力就分担到了不同的库上面。 数据分片 数据分片包括里:垂直分片和水平分片,垂直分…

SSM志愿服务管理小程序-计算机毕业设计源码97923

摘 要 随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,志愿服务管理小程序被用户普遍使用,方便用户能…

基于Vue的神影视频APP

需求说明:使用Vue脚手架进行搭建,页面简洁、精致,和一些常见的电影网站类似,例如支付宝中的“淘票票电影”。在项目中使用页面布局技术(表格,vue.js框架,DIV+CSS或者混合使用)进行页面设计,使网站功能齐全,界面美观大方,有一定的交互性。 功能分析:系统主要分为七…

低代码与人工智能:改变软件开发的未来

引言 在当今快速发展的科技时代,软件开发行业也在不断地创新和演进。其中,低代码开发和人工智能技术是两个备受关注的领域,低代码开发通过简化开发流程和降低编码难度,使得软件开发变得更加高效和便捷,而人工智能技术…

Redis使用Set实现点赞功能

文章目录 set 数据类型介绍不排序实现排序实现 set 数据类型介绍 Redis中的set类型是一组无序的字符串值。 set通过其独特的数据结构和丰富的命令提供了在存储和处理集合元素方面的一些非常有用的功能。下面列出了主要的set类型命令: SADD key member1 [member2]&a…

Python筑基之旅-文件(夹)和流

目录 一、文件操作 1、文件打开与关闭 2、文件读写 3、文件操作模式 4、文件编码 二、文件夹操作 1、创建文件夹 2、删除文件夹 3、改变当前工作目录 4、获取当前工作目录 5、检查文件/文件夹是否存在 6、遍历文件夹 三、文件路径操作 1、获取绝对路径 2、构建完…

【设计模式】JAVA Design Patterns——Data Access Object(数据访问对象模式)

🔍目的 对象为某种类型的数据库或其他持久性机制提供了抽象接口。 🔍解释 真实世界例子 有一组客户数据需要持久化到数据库中。 我们需要整个额外的增删改查操作以便操作客户数据。 通俗描述 DAO是我们通过基本持久性机制提供的接口。 维基百科 在计算机…

电脑微信群发 500 1000人以上怎么群发,微信营销群发助手软件,本人亲测,增加十倍业绩!!!

今天给大家推荐一款我们目前在使用的电脑群发工具掘金小蜜,不仅可以无限多开,方便你同时管理多个账号,群发功能更是十分强大,轻松释放你的双手。 掘金小蜜(只支持Win7及以上操作系统,没有推Mac版和手机客户…

【应用层】域名系统DNS

目录 1、互联网的域名结构 2、域名服务器 域名系统 DNS (Domain Name System) 是互联网使用的命名系统,用来把便于人们使用的机器名字转换为 IP 地址,域名系统其实就是名字系统。 互联网的域名系统 DNS 被设计成为一个联机分布式数据库系统&#xff0c…