redis高级数据结构HyperLogLog

文章目录

  • 背景
  • 常见API
  • 注意事项
  • 实现原理
    • 1、哈希函数
    • 2、前导零统计
    • 3、存储与计数
    • 4、基数估算
  • pf 的内存占用为什么是 12k?
  • 总结

背景

在开始这一节之前,我们先思考一个常见的业务问题:如果你负责开发维护一个大型的网站,有一天老板找产品经理要网站每个网页每天的 UV 数据,然后让你来开发这个统计模块,你会如何实现?

如果统计 PV 那非常好办,给每个网页一个独立的 Redis 计数器就可以了,这个计数器的 key 后缀加上当天的日期。这样来一个请求, incrby 一次,最终就可以统计出所有的 PV数据。

但是 UV 不一样,它要去重,同一个用户一天之内的多次访问请求只能计数一次。这就要求每一个网页请求都需要带上用户的 ID,无论是登陆用户还是未登陆用户都需要一个唯一ID 来标识。

你也许已经想到了一个简单的方案,那就是为每一个页面一个独立的 set 集合来存储所有当天访问过此页面的用户 ID。当一个请求过来时,我们使用 sadd 将用户 ID 塞进去就可以了。通过 scard 可以取出这个集合的大小,这个数字就是这个页面的 UV 数据。没错,这是一个非常简单的方案。

但是,如果你的页面访问量非常大,比如一个爆款页面几千万的 UV,你需要一个很大
的 set 集合来统计,这就非常浪费空间。如果这样的页面很多,那所需要的存储空间是惊人的。为这样一个去重功能就耗费这样多的存储空间,值得么?其实老板需要的数据又不需要太精确, 105w 和 106w 这两个数字对于老板们来说并没有多大区别, So,有没有更好的解决方案呢?

这就是本节要引入的一个解决方案, Redis 提供了 HyperLogLog 数据结构就是用来解决这种统计问题的。 HyperLogLog 提供不精确的去重计数方案,虽然不精确但是也不是非常不精确,标准误差是 0.81%,这样的精确度已经可以满足上面的 UV 统计需求了。

HyperLogLog 数据结构是 Redis 的高级数据结构,它非常有用,但是令人感到意外的
是,使用过它的人非常少。

常见API

HyperLogLog 提供了两个指令 pfadd 、 pfcount和pfmerge,根据字面意义很好理解,一个是增加计数,一个是获取计数。 pfadd 用法和 set 集合的 sadd 是一样的,来一个用户 ID,就将用户 ID 塞进去就是。 pfcount 和 scard 用法是一样的,直接获取计数值。pfmerge用于将多个 pf 计数值累加在一起形成一个新的 pf 值(比如在网站中我们有两个内容差不多的页面,运营说需要这两个页面的数据进行合并。其中页面的 UV 访问量也需要合并,那这个时候 pfmerge 就可以派上用场了)。

HyperLogLog API中pf* 这个 pf 是什么意思?
它是 HyperLogLog 这个数据结构的发明人 Philippe Flajolet 的首字母缩写。

注意事项

HyperLogLog 这个数据结构不是免费的,不是说使用这个数据结构要花钱,它需要占据一定 12k 的存储空间,所以它不适合统计单个用户相关的数据。如果你的用户上亿,可以算算,这个空间成本是非常惊人的。但是相比 set 存储方案, HyperLogLog 所使用的空间那真是可以使用千斤对比四两来形容了。

不过你也不必过于当心,因为 Redis 对 HyperLogLog 的存储进行了优化,在计数比较
小时,它的存储空间采用稀疏矩阵存储,空间占用很小,仅仅在计数慢慢变大,稀疏矩阵占用空间渐渐超过了阈值时才会一次性转变成稠密矩阵,才会占用 12k 的空间。

实现原理

在这里插入图片描述

1、哈希函数

  • 作用:使用一个强散列函数将输入的元素映射为固定长度的二进制串。这个哈希函数能保证输出的哈希值均匀分布,使得每个二进制位上出现0和1的概率均等,从而保证了统计的准确性。
  • 举例:假设有元素“user1”“user2”等,经过哈希函数处理后,会得到对应的二进制串,如“user1”可能被哈希为“10100100”。

2、前导零统计

  • 计算方法:对于每个元素经过哈希后的二进制串,统计从最高位开始连续零的个数,即前导零个数。前导零个数反映了元素哈希值的稀有程度,间接表示了元素的独特性。
  • 举例:对于二进制串“10100100”,从最高位开始连续的零有2个,所以其前导零个数为2。一般来说,前导零个数越多,该元素的哈希值就越稀有,在整个数据集中越独特。

3、存储与计数

  • 桶数组:Redis中的HyperLogLog结构内部维护了一个大小固定的桶数组,默认大小为
    2^14=16384个桶。每个桶用于存储对应的元素哈希值所观察到的最大前导零个数。
  • 更新操作:当添加新的元素时,它会被哈希并找到对应的桶来更新该桶中的最大前导零计数值。如果新元素的前导零个数大于当前桶中存储的值,则更新桶中的值为新元素的前导零个数。

4、基数估算

  • 计算方式:利用统计的所有桶中最长的前导零序列,通过预定义的公式计算出一个近似的基数(唯一元素数量)。这个公式基于概率论和统计学原理,通过对桶中最大前导零计数值的分析,推算出整个数据集的基数。
  • 误差控制:标准误差大约是0.81%,这意味着对于大量数据,HyperLogLog能够以相对较小的误差估计基数。

pf 的内存占用为什么是 12k?

在 Redis 的 HyperLogLog实现中用到的是 16384 个桶,也就是 2^14,每个桶的 maxbits 需要 6 个 bits 来存储,最大可以表示 maxbits=63,于是总共占用内存就是 2^14 * 6 / 8 = 12k 字节。

总结

HyperLogLog 数据结构来进行估数,它非常有价值,可以解决很多精确度不高的统计需求。但是如果我们想知道某一个值是不是已经在 HyperLogLog 结构里面了,它就无能为力了,它只提供了 pfadd 和 pfcount 方法,没有提供 pfcontains 这种方法。HyperLogLog 底层通过桶、hash函数来对数据进行存储。

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

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

相关文章

<tauri><rust><GUI>基于rust和tauri,在已有的前端框架上手动集成tauri示例

前言 本文是基于rust和tauri,由于tauri是前、后端结合的GUI框架,既可以直接生成包含前端代码的文件,也可以在已有的前端项目上集成tauri框架,将前端页面化为桌面GUI。 环境配置 系统:windows 10 平台:visu…

mysql 学习11 事务,事务简介,事务操作,事务四大特性,并发事务问题,事务隔离级别

一 事务简介, 数据库准备: create table account(id int auto_increment primary key comment 主键ID,name varchar(128) not null comment 姓名,backaccountnumber char(18) unique comment 银行账号,money float comment 余额 )comment 银行账号表;…

重塑生产制造企业项目管理新范式:项目模板在Tita中的卓越实践

在竞争激烈的生产制造领域,每一个项目的成功执行都是企业稳健前行的重要基石。然而,面对复杂多变的生产流程、严格的交货期限以及不断变化的客户需求,如何确保项目高效、有序地进行,成为了众多企业面临的共同挑战。此时&#xff0…

Ajax-介绍

概念: Asynchronous JavaScript And XML,异步的JavaScript和XML. 作用: 数据交换:通过Aiax可以给服务器发送请求,并获取服务器响应的数据 异步交互: 可以在不重新加载整个页面的情况下,与服务器交换数据并更新部分网页的技术, 如:搜索联想、…

基于可信数据空间的企业数据要素与流通体系建设(附ppt 下载)

近期,可信数据空间会议召开。大数据系统软件国家工程研究中心总工程师王晨发表了题为《基于可信数据空间的企业数据要素与流通体系建设》主旨演讲。 WeChat Subscription Account【智慧城市指北】,可搜索相关关键字“20250107”,可获取具体获…

idea整合deepseek实现AI辅助编程

1.File->Settings 2.安装插件codegpt 3.注册deepseek开发者账号,DeepSeek开放平台 4.按下图指示创建API KEY 5.回到idea配置api信息,File->Settings->Tools->CodeGPT->Providers->Custom OpenAI API key填写deepseek的api key Chat…

Composo:企业级AI应用的质量守门员

在当今快速发展的科技世界中,人工智能(AI)的应用已渗透到各行各业。然而,随着AI技术的普及,如何确保其可靠性和一致性成为了企业面临的一大挑战。Composo作为一家致力于为企业提供精准AI评估服务的初创公司,通过无代码和API双模式,帮助企业监测大型语言模型(LLM)驱动的…

增加工作台菜单页面,AI问答应用支持上下文设置,数据库表索引优化,zyplayer-doc 2.4.8 发布啦!

zyplayer-doc是一款适合企业和个人使用的WIKI知识库管理工具,支持在线编辑富文本、Markdown、表格、Office文档、API接口、思维导图、Drawio以及任意的文本文件,专为私有化部署而设计,最大程度上保证企业或个人的数据安全,支持以内…

C++开发(软件开发)常见面试题

目录 1、C里指针和数组的区别 2、C中空指针请使用nullptr不要使用NULL 3、http/https区别和头部结构? 4、有了mac地址为什么还要ip地址?ip地址的作用 5、有了路由器为什么还要交换机? 6、面向对象三大特性 7、友元函数 8、大端小端 …

智能理解 PPT 内容,快速生成讲解视频

当我们想根据一版 PPT 制作出相对应的解锁视频时,从撰写解锁词,录制音频到剪辑视频,每一个环节都需要投入大量的时间和精力,本方案将依托于阿里云函数计算 FC 和百炼模型服务,实现从 PPT 到视频的全自动转换&#xff0…

第八届大数据与应用统计国际学术研讨会(ISBDAS 2025)

重要信息 官网:www.is-bdas.org 时间:2025年2月28-3月2日 地点:中国 广州 主办单位:广东省高等教育学会人工智能与高等教育研究分会 协办单位:北京师范大学人工智能与未来网络研究院、人工智能与大数据科研基地 …

认识O(NlogN)的排序

归并排序 归并排序(任何一个递归)如果不懂可以画一个树状结构去帮助自己去理解。 核心排序方法为Merger public class 归并排序 {public static void main(String[] args) {int[] arr1 {3, 1, 2, 2, 5, 6};int[] arr2 Arrays.copyOf(arr1, arr1.len…

方波的基波和谐波详细推导,以及matlab验证[电路原理---2]

最近要滤波,从1KHZ 方波中获得正弦波,这让我们要对方波的频谱有具体的了解。虽然楼主一年前刚学过傅里叶。但也是忘的干干净净查阅资料后终于是整理出来。用漂亮的latex打出来了,为自己留存一份记录,也分享给大家学习。 方波的基…

计算机组成原理(3)

计算机组成原理(3) 存储器层次结构存储器概述存储器分类存储器性能指标 半导体随机存储SRAM和DRAM 存储器层次结构 主存-辅存:实现了虚拟存储系统,解决了主存容量不足的问题; Cache-主存:解决了主存于CPU速…

2024最新版Java面试题及答案,【来自于各大厂】

发现网上很多Java面试题都没有答案,所以花了很长时间搜集整理出来了这套Java面试题大全~ 篇幅限制就只能给大家展示小册部分内容了,需要完整版的及Java面试宝典小伙伴点赞转发,关注我后在【翻到最下方,文尾点击名片】即可免费获取…

DeepSeek-V3 论文解读:大语言模型领域的创新先锋与性能强者

论文链接:DeepSeek-V3 Technical Report 目录 一、引言二、模型架构:创新驱动性能提升(一)基本架构(Basic Architecture)(二)多令牌预测(Multi-Token Prediction&#xf…

Mac 基于Ollama 本地部署DeepSeek离线模型

最近节日期间最火的除了《哪吒》就是deepseek了,毕竟又让西方各个层面都瑟瑟发抖的产品。DeepSeek凭借其强大的AI能力真的是在全球多个领域展现出强大的影响力。由于受到外部势力的恶意攻击倒是deepseek官方服务不稳定,国内其他厂家的适配版本也不是很稳…

51单片机之引脚图(详解)

8051单片机引脚分类与功能笔记 1. 电源引脚 VCC(第40脚):接入5V电源,为单片机提供工作电压。GND(第20脚):接地端,确保电路的电位参考点。 2.时钟引脚 XTAL1(第19脚&a…

力扣刷题 题11,12

题目11 思路&#xff1a;设置左右指针 left和 right 指针指向数组的开始和末尾&#xff0c;max_water 用于记录最大容量初始为0。利用while循环left<right&#xff0c;移动指针比较数组元素 height[left] 和 height[right] 的大小&#xff0c;移动较短的那条线的指针&#x…

使用Python实现PDF与SVG相互转换

目录 使用工具 使用Python将SVG转换为PDF 使用Python将SVG添加到现有PDF中 使用Python将PDF转换为SVG 使用Python将PDF的特定页面转换为SVG SVG&#xff08;可缩放矢量图形&#xff09;和PDF&#xff08;便携式文档格式&#xff09;是两种常见且广泛使用的文件格式。SVG是…