Redis--HyperLogLog的指令语法与使用场景举例(UV统计)

文章目录

      • 前言
      • HyperLogLog介绍
      • HyperLogLog指令使用
      • 使用场景:UV统计

前言

  • Redis除了常见的五种数据类型之外,其实还有一些少见的数据结构,如Geo,HyperLogLog等。虽然它们少见,但是作用却不容小觑。本文将介绍HyperLogLog指令的语法和使用场景。

HyperLogLog介绍

  • HyperLogLog是Redis提供的一种不准确(标准误差为0.81%)的去重计数方案。
  • 提到去重计数,第一个想到的数据结构就是集合set,set集合可以保存数据,并用scard准确地返回集合中的数据条数,但是若数据量很大,那么使用set集合就需要相当大的存储空间,这显然不是我们想看到的结果,而对于某些统计其实并不需要特别精确的结果。
  • 对于这种情况,HyperLogLog就可以发挥大用,HyperLogLog的优势在于无论存储的数据量有多大,它都只需要12KB的存储空间(可以计算接近2^64个不同的基数)。当然它只能统计数据集的个数,而不直接存放元素,不能试图用它保存元素。另外HyperLogLog对数据集的统计也不是完全准确的,存在一定误差,可能比实际情况多或少。

HyperLogLog指令使用

  • 增加计数: pfadd key element [element…]
    在这里插入图片描述

  • 查询计数: pfcount key
    在这里插入图片描述

  • 将多个HyperLogLog合并到一个HyperLogLog中: pfmerge destkey sourcekey [sourcekey …]
    在这里插入图片描述

使用场景:UV统计

  • HyperLogLog最适合的使用场景就是做UV的统计了,简直量身定制一般。一个爆款页面的UV可能有几千万,使用HyperLogLog可以节约存储空间,并且UV的统计允许存在一定的误差。

    补充:

    • pv(page view,浏览量)
      • 页面的浏览次数,衡量网站用户访问的网页数量;
      • 用户每打开一个页面就记录1次,多次打开同一页面则浏览量累计。
    • uv(unique visitor,独立访客)
    • 1天内访问某站点的人数(以cookie为依据);
    • 1天内同一访客的多次访问只计为1个访客。
    • ip(独立ip)
    • 指1天内使用不同ip地址的用户访问网站的数量;
    • 同一IP不管访问了几个页面,独立IP数均为1。
  • 代码实现: 在代码中提供了三个方法,分别对应pfadd添加页面的UV,pfcount获取页面的UV统计结果和pfmerge合并指定页面UV。

    public class UVByHyperLogLog {public static void main(String[] args) {Jedis jedis = new Jedis("127.0.0.1");jedis.del(UV_PAGE_1);jedis.del(UV_PAGE_2);jedis.del(UV_PAGE_1_2);for (int i = 0; i < 10000; i++) {String userid = "userid:"+Math.random()*100000;addCount(UV_PAGE_1,userid,jedis);}System.out.println("页面一的UV:"+getCount(UV_PAGE_1,jedis));jedis.del(UV_PAGE_2);for (int i = 0; i < 5000; i++) {String userid = "userid:"+Math.random()*100000;addCount(UV_PAGE_2,userid,jedis);}System.out.println("页面二的UV:"+getCount(UV_PAGE_2,jedis));//页面一和页面二合并后的UV 合并与的UV不等于两个UV的相加,一样是不精确的mergeCount(UV_PAGE_1_2, new String[]{UV_PAGE_1, UV_PAGE_2},jedis);System.out.println("合并后两个页面的UV总数"+getCount(UV_PAGE_1_2,jedis));}private static final String UV_PAGE_1 = "UV_PAGE_1";private static final String UV_PAGE_2 = "UV_PAGE_2";private static final String UV_PAGE_1_2 = "UV_PAGE_1_2";/*** 向HyperLogLog添加数据* @param key UV_KEY* @param userId 用户Id* @param jedis*/public static void addCount(String key, String userId,Jedis jedis){jedis.pfadd(key,userId);}/*** 返回统计的结果* @param key* @param jedis* @return*/public static long getCount(String key,Jedis jedis){return jedis.pfcount(key);}/*** 将多个pf计数合并为一个pf计数* @param newKey 合并后的新HyperLogLog的key* @param keys  要合并的HyperLogLog的key* @param jedis* @return*/public static void mergeCount(String newKey,String[] keys,Jedis jedis){jedis.pfmerge(newKey,keys);}
    }
    
  • 测试结果:在上述main方法中,第一个for循环,模拟10000个用户访问页面一,第二个for循环模拟5000个用户访问页面二,通过HyperLogLog进行UV统计,输出统计结果,最后合并两个页面的统计值,观察结果后发现,HyperLogLog统计后的结果与实际结果存在误差,但是在数据量很大的情况下,这点误差误伤大雅。:
    在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

微信小程序首页、界面布局、功能简洁(示例三)

微信小程序首页界面布局、页面简洁&#xff0c;功能简单 直接上具体代码&#xff1a; 1、js代码 Page({/*** 页面的初始数据*/data: {imgList: [../../images/demo.jpg, ../../images/demo.jpg, ../../images/demo.jpg],navList: [{src: ../../images/nav1.png,title: 菜单一}…

鸿蒙开发系列教程(八)--ArkTS语言:IF-ELSE渲染

条件渲染 if/else Entry Component struct ViewA1 {State count: number 0;build() {Column() {Text(计数${this.count})if (this.count 5) {Text(数字等于5).fontColor(Color.Green)} else {Text(数字不等于5).fontColor(Color.Red)}Button(增加).onClick(() > {this.cou…

理想汽车大模型算法工程师面试,被问的瑟瑟发抖。。。。

最近我们技术群的一位小伙伴&#xff0c;分享了他面试理想汽车大模型算法工程师的经历与经验。 今天整理后分享给大家&#xff0c;如果你对这块感兴趣&#xff0c;可以文末加入我们的技术&面试讨论群 一面&#xff08;1.5h&#xff0c;感觉有点难&#xff09; 自我介绍&…

CPU中的算术逻辑单元(ALU)

ALU有2个单元&#xff0c;1个算术单元和1个逻辑单元 算数单元 1 bit加法 半加器 由一个异或门&#xff08;XOR&#xff09;和与门&#xff08;AND&#xff09;两个逻辑门构成&#xff0c;异或门表示无进位加法&#xff08;sum&#xff09;&#xff0c;而与门表示进位&…

解决 Git:ssh: connect to host github.com port 22: Connection timed out 问题的三种方案

1、问题描述&#xff1a; 其一、整体提示为&#xff1a; ssh: connect to host github.com port 22: Connection timed out fatal: Could not read from remote repository. 中文为&#xff1a; ssh&#xff1a;连接到主机 github.com 端口 22&#xff1a;连接超时 fatal&a…

在IntelliJ IDEA中通过Spring Boot集成达梦数据库:从入门到精通

目录 博客前言 一.创建springboot项目 新建项目 选择创建类型​编辑 测试 二.集成达梦数据库 添加达梦数据库部分依赖 添加数据库驱动包 配置数据库连接信息 编写测试代码 验证连接是否成功 博客前言 随着数字化时代的到来&#xff0c;数据库在应用程序中的地位越来…

在Go中处理HTTP请求和响应

在Go语言中&#xff0c;处理HTTP请求和响应的关键在于对net/http包的理解和使用。这个包提供了强大的工具&#xff0c;使开发者能够轻松地构建Web应用程序。以下是一个简单的示例&#xff0c;展示了如何在Go中处理HTTP请求和响应。 首先&#xff0c;确保你已经安装了Go语言的开…

spring Cloud Stream 实战应用深度讲解

springCloudStream 简介 Spring Cloud Stream是一个框架&#xff0c;用于构建与共享消息传递系统连接的高度可扩展的事件驱动微服务。 该框架提供了一个灵活的编程模型&#xff0c;该模型建立在已经建立和熟悉的 Spring 习惯用语和最佳实践之上&#xff0c;包括对持久发布/订…

springboot家乡特色推荐系统源码和论文

在Internet高速发展的今天&#xff0c;我们生活的各个领域都涉及到计算机的应用&#xff0c;其中包括家乡特色推荐的网络应用&#xff0c;在外国家乡特色推荐系统已经是很普遍的方式&#xff0c;不过国内的管理网站可能还处于起步阶段。家乡特色推荐系统采用java技术&#xff0…

python数据和分析——pandas基础内容

Pandas 的两个主要的数据结构是 Series 和 DataFrame&#xff1a; Series 是一维标记数组&#xff0c;类似于带有标签的列表。它可以包含不同类型的数据&#xff0c;并且可以通过索引进行访问和操作。DataFrame 是二维表格型数据结构&#xff0c;类似于 SQL 表或 Excel 电子表…

Apipost自动化测试+Jenkins实现持续集成

Apipost 自动化测试支持「持续集成」功能&#xff0c;在安装了Apipost的服务器中输入命令&#xff0c;即可运行测试脚本。 创建自动化测试脚本 在创建好的测试用例中选择「持续集成」。 点击新建&#xff0c;配置运行环境、循环次数、间隔停顿后点击保存会生成命令。 安装 Ap…

Python列表与元组

Python 列表和元组是Python编程语言中两种重要的数据结构&#xff0c;它们在实际的编程中扮演着不可或缺的角色。本文将深入探讨Python列表和元组的特性、用法以及它们之间的区别&#xff0c;帮助读者更好地理解和运用这两种数据结构。 Python 列表 Python 列表是一种有序、可…