Redis数据结构之HypeLogLog原理

HyperLogLog 使用及其算法原理详细讲解 由于篇幅限制,小编在此截出几张知识讲解的图解《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!**如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)由于篇幅限制,小编在此截出几张知识讲解的图解[外链图片转存中…(img-duEyrRFK-1713384152731)][外链图片转存中…(img-ylLw0z95-1713384152731)] 阅读详情

统计UV的实现方式

  1. Set
  2. bitmap
  3. Redis杀器HypeLogLog

1. Set实现

为了统计页面UV,及不重复的所有用户,我们可以建立一个Set的结构,存储所有访问页面的用户ID,根据Set的特性,我们可以保证每个ID只出现一次,从而得出UV,但这样会存在内存问题,假设每个ID为一个Integer,4字节,那么存储10亿个用户需要4G的内存空间,如果多统计几个页面,这得多少空间,太浪费了。

2. bitmap实现

用bitmap的好处是一个字节可以存储8个数,如果存储10亿个ID,1000000000/8/1024/1024 = 119.2M,相对于Set的实现,节省了40倍的空间,可能对一般小公司,足以,然而,对于海量数据怎么办。

3.1 HypeLogLog介绍

Redis 在 2.8.9 版本添加了 HyperLogLog 结构。Redis HyperLogLog是用来做基数统计的算法,**HyperLogLog的优点是,在输入元素的数量或者体积非常非常大时,计算基数所需的空间总是固定 的、并且是很小的。**在 Redis 里面,每个 HyperLogLog 键只需要花费 12 KB 内存,就可以计算接近 2^64 个不同元素的基数。这和计算基数时,元素越多耗费内存就越多的集合形成鲜明对比。但是,因为 HyperLogLog 只会根据输入元素来计算基数,而不会储存输入元素本身,所以 HyperLogLog 不能像集合那样,返回输入的各个元素。

3.2 HypeLogLog原理

HypeLogLog是概率学算法,只要数据量足够大,统计的结果就会无限的趋近于精确,搞懂原理前,我们先学学基本概率知识。

3.2.1 伯努利试验

伯努利试验指的是单次事件,而这次事件的结果是两个可能性结果中的一个。这样的事件都可以表达成“是或否”(“yes or no”)问题。例如:

  • 硬币掉落后是人头朝上吗?
  • 刚出生的小孩是个女孩吗?

因此结果称为“成功”和“失败”,而结果不应该照字面推断。伯努利试验的例子包括:

  • 抛硬币。在这里,正面(人头面)通常表示成功而反面(刻字面)表示失败。一枚均匀硬币,按照定义成功机会是一半p=1/2。
  • 掷骰子,在这个例子里我们称六是"成功"而其他都是"失败",p=1/6。

在数学上,这样的试验是以随机变量为模型,而随机变量只能有两个值:0和1,1被认为是"成功"。在单次的伯努利试验中,如果 p 是成功的概率,那么将呈现伯努利分布,此时随机变量的期望值就是 p。

一个伯努利过程(Bernoulli process)是由重复出现独立但是相同分布的伯努利试验组成,例如抛硬币十次,而此时呈现之结果将呈现二项分布。

3.2.2 原理

概率告诉我们,如果我们进行无数次的伯努利试验,那么,最终成功的机率就是概率,也就是说,如果我们抛硬币无数次,人头朝上的概率就是1/2,如果掷骰子无数次,6的概率就是1/6.那么,如果你告诉我说:你最近掷骰子,出现了一次如下情况,连续3次都是6,那么我计算本次事件发生的概率为(1/6)^3,即1/216,那么我告诉你,你可能掷骰子的次数是216次,因为出现该事件的概率是1/216,而你恰恰只出现了一次这样的事件。

HypeLogLog基本就是这样的一个原理,但这样做误差可能很大,比如你就掷骰子3次,3次都为6,我却说你掷了216,为了解决误差问题,我让你同时掷3个骰子,掷很多次,最后你告诉我每个骰子连续出现6的最大次数,比如分别为3, 1, 2,按照概率我计算得到216次,6次,36次,最后我取加权平均数3/(1/216 + 1/6 + 1/36)=15次,15*3=45,这样相对只用一个骰子进行试验误差就会小一些,道理很简单,就是放大样本量,比如有一些调研问卷,只让一个年龄段的人填结论总是有误差的,于是就需要多个年龄段的人填,以此减小误差。

3.2.3 HypeLogLog和伯努利

上面掷骰子的例子中,成功概率为1/6,在HypeLogLog中,它是这么计算的,一个值V,经过hash(V)后得到了hv,hv换算为2进制,每个位置出现0和1的概率是相同的,为1/2,那么每个数都可以当做是一轮伯努利试验,把从低位开始,出现联系个0的次数记为K(和上面连续出现6的次数是一个道理),然后根据K估计样本量大小。为减小误差,就多进行几轮试验,于是HypeLogLog出现了分桶逻辑。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FXd0sl6p-1599968649440)(7198623A5C94442F9BC90CB524C2FA63)]

在HypeLogLog中,一个值会被Hash为一个64位的二进制数,Hash结果的前14位进行分桶,共有2^14=16384个桶,后面的50位作为一轮伯努利试验,那么最坏情况下,连续50次都出现了0,那么在对应的桶中记下50。50用二进制表示:110010,为6位,因此每个桶用6bit进行存储。
举个栗子:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Q681Gc3D-1599968649441)(2889A9C37C014032BCF97FC3D884A54F)]

最后计算公式:

DV_{HLL}=const*m*{m\over{\sum_{i=1}^m{1\over 2^{R_i}}}}

const为常数,m为桶的数量,最后一部分为根据每个桶里的值计算的加权平均数,即常量*桶*加权平均数,这里的2是因为每个位置为0的概率都为1/2.

这就是hypeLogLog的原理。

3.2.4 空间计算

共2^14 =16834个桶,每个桶用6bit存数据,每个哈希值64位,因此可以用2^14 *6/8/1024=12K就可以存储2^64 个数据。

4.HLL操作

PFADD key value [value...] // 将指点元素加入HLL
PFCOUNT key [key...]返回给的key的基数概率估计值
PFMERGE destKey sourceKey [sourceKye...]合并多个HLL到一个Key为destKey的HLL中

参考文献

https://juejin.im/post/6844903785744056333

http://content.research.neustar.biz/blog/hll.html

https://zh.wikipedia.org/wiki/%E4%BC%AF%E5%8A%AA%E5%88%A9%E5%88%86%E5%B8%83

https://zh.wikipedia.org/wiki/%E4%BC%AF%E5%8A%AA%E5%88%A9%E8%A9%A6%E9%A9%97

http://antirez.com/news/75

Redis系列-HyberLogLog 算法 相信很多同学在面试的时候都遇到过一些大数据题目, 我的很大,你忍一下。假设现在面试官就现场出了一道题,有一个日活量很高的网站,现在需要你大致统计一下这个网站的日活量,但是呢,这个电脑可用的内存,只有几十KB,如何较为精确地统计网站的日活量?如何解决这个问题,就需要用到HyberLogLog算法。HyberLogLog算法是一种概率性统计算法,其可以仅用12kb的内存大小统计2642^{64}264个数的基数(不同个数),而误差不会超过1%。 阅读详情

相关推荐

redis每种数据结构对应的底层数据结构原理

Redis 的每种数据结构(String、List、Hash、Set、Sorted Set)在底层都采用了不同的实现方式,根据数据规模和特性动态选择最优的编码(encoding)以节省内存和提高性能。

zhglhy的专栏 747

玩转Redis-HyperLogLog原理探索

《玩转Redis》系列文章主要讲述Redis的基础及中高级应用。本文是《玩转Redis》系列第【10】篇。本文关键字:玩转Redis、HyperLogLog原理、基数缓存、密集存储结构和稀疏存储结构。

zxiaofan.com 4804

Redis-Redis 高级数据结构 HyperLogLog与事务

如果这样的页面很多,那 所需要的存储空间是惊人的。为这样一个去重功能就耗费这样多的存储空间,值 得么?该实现一个明显的问题是内存占用过多,所有从库的连接在主库上是独立的,同样举抛硬币的例子,如果只有一组抛硬币实验,显然根据公式推导得到的。那么基于上面的估算结论,我们可以通过多次抛硬币实验的最大抛到正面的。大家应该对事务比较了解,简单地说,事务表示一组动作,要么全部执行,但是,如果你的页面访问量非常大,比如一个爆款页面几千万的 UV。列中的未执行命令,并不会回滚已经操作过的数据,这一点要和关系型数据库的。

weixin_43874650的博客 1345

2022黑马Redis跟学笔记.实战篇(七)

2022黑马Redis跟学笔记.实战篇(七)

心向阳光的天域的博客 629

Redis原理及redis核心数据结构与场景,及常见面试题

Redis作为高性能内存数据库,其核心原理包括:单线程模型(避免竞争)、I/O多路复用、高效数据结构(哈希表/跳跃表等)和混合持久化机制(RDB快照+AOF日志)。提供丰富的数据结构如String、Hash、List、Set等,支持缓存、队列、排行榜等场景。高可用方案包括主从复制、哨兵和集群模式,通过分片槽位实现数据分布。内存淘汰策略涵盖LRU、LFU等算法,防止内存溢出。典型问题如缓存穿透/雪崩可通过布隆过滤器、随机过期时间等方案解决。

bestlove12345的博客 809

Yolov5自学笔记之一--从入门到入狱,功能强大不要乱用(实现yolov5的基本功能使用流程及训练自己的数据集)

零基础自学yolov5,学会简单使用和训练自己的数据集,在自己工作中使用

qq_41597915的博客 1万+

关于Redis中Hypeloglog数据结构为什么内存小,效率高

HyperLogLog 是一种用于基数统计(distinct counting)的概率算法,能够在极小内存占用下(通常只需几KB)估算巨大数据集的基数(不重复元素数量),标准误差约为 0.81%。

gwndjsh的博客 1026

LangChain4j + Milvus 从0-1实现会话管理与RAG检索的AIChat超详细教程

本教程将介绍如何使用LangChain4j和Milvus向量数据库构建一个具备流式输出、会话管理、会话隔离和基于文档RAG检索能力的AI机器人。我们将使用阿里百炼模型作为LLM后端,并通过Docker部署Milvus向量数据库。创建Assistant接口,定义聊天服务:LangChain4j 中文文档 | LangChain4j 中文文档wiringMode :这个属性一般两种,一种是自动装配,我们这里选择手动配置。

2301_80014343的博客 1436

Redis 数据结构详解

redis常用五种数据类型和三种特殊数据类型。

一名后端程序猿 8035

阻抗控制器实现机器人关节运动控制

本文先对做个简单的介绍,具体内容后续再更,其他模块可以参考去我其他文章如:PID反馈控制器、前馈控制器、前馈+反馈控制器等等如:机械臂模型(几何解算)控制器、小车底盘运动学模型(几何解算)的控制器、四足机器人模型(预测迭代)的控制器等等如:微分平坦(无人机的轨迹跟随)等等如:MPC优化控制算法如:线性二次调节器(LQR)是基于模型的控制器,使用车辆状态来使误差最小化,Apollo使用LQR进行横向控制。横向控制包含四个组件:横向误差、横向误差的变化率、朝向误差和朝向的变化率。

qq_35635374的博客 365

基于YOLOv8的端面小目标计数解决方案: 多头检测器+小缺陷到大缺陷一网打尽的GiraffeDet+Wasserstein Distance Loss | 助力工业小目标缺陷检测

端面小目标计数部署解决方案 | 亲测在工业小目标缺陷涨点明显,原始mAP@0.5 0.936提升至0.955

①答疑群聊服务;②YOLO大模型知识问答系统;③计算机视觉论文生成智能体; 1955

Redis数据结构——HyperLogLog 原理

HyperLogLog是一种高效的基数计数概率算法,通过极小内存(仅12KB)即可统计近2^64个不同元素。它基于LogLog算法改进,利用分桶和调和平均数降低误差(标准误差0.81%)。Redis实现中采用16384个桶,每个桶6bit,通过哈希将数据分散到桶中并记录最大连续零位数。相比HashMap等传统方法,HyperLogLog在百万级数据量时内存优势显著,适合允许微小误差的大规模去重统计场景,如日活用户统计。其核心思想源自伯努利试验,将统计问题转化为概率估算,展现了数学在工程中的巧妙应用。

NoviceZ的博客 406

《多模态融合改进》目录一览 | 专栏介绍 :全网 第一份 完整的多模态改进教程,提供《多模态模型改进完整项目包》-开箱即用

在大家订阅专栏后,便可获得多模态模型改进完整项目包-开箱即用,方便简单

Limiiiing的博客 1万+

Redis都有哪些数据结构,使用场景与原理解析

Redis GEO 底层使用 ZSet,score 是地理位置转为整数 score 的编码值。(key = 用户,field = 商品ID,value = 数量)是 Redis 自定义的字符串类型,支持动态扩容、安全、长度记录。不能存重复数据,若需要统计次数,用 Hash 或 ZSet 替代。本质是字符串,内部按位存储,1bit 表示一个状态。每条消息是一个有序条目(ID 唯一),支持消费确认。✅ String:字符串(最常用、最简单的类型)使用时建议一个用户一个 key,方便管理和清理。

MarkerHub的博客 701

核心组件大换血:Backbone与Neck魔改篇:YOLO26结合StarNet结构:2026星状网络在YOLO生态的即插即用实战

本文将介绍如何将StarNet作为Backbone替换YOLO26原生架构,以提升边缘设备上的目标检测性能。文章首先分析了YOLO26在特定场景下的精度瓶颈,指出其通用Backbone设计存在不足。随后深入解析StarNet的核心创新——星操作(Star Operation),这一低维计算却能获得高维特征表达的数学魔术,以及其极简的StarBlock模块设计。通过对比YOLO26原生架构的三大创新与痛点,作者提出两种替换策略:完整替换Backbone或局部替换+Neck联调。文中提供了StarNet核心代码

ZDQ58818的博客 290

RK3568平台开发系列讲解(中断及异常篇)中断下半部:中断线程化

以前用 work 来线程化地处理中断,一个 worker 线程只能由一个 CPU 执行, 多个中断的 work 都由同一个 worker 线程来处理,在单 CPU 系统中也只能忍着 了。少数中断不能线程化,典型的例子是时钟中断,有些流氓进程不主动让出处理器,内核只能依靠周期性的时钟中断夺回处理器的控制权,时钟中断是调度器的脉搏。中断处理线程是优先级为50、调度策略是SCHED_FIFO的实时内核线程,名称是“irq/”后面跟着Linux中断号,线程处理函数是。,说明是线程化的中断,那么唤醒中断处理线程。

内核笔记 435

深入解析 Redis 原理:架构、数据结构与高效存储

Redis 是一款高性能的内存键值数据库,以其单线程 + 多路复用的架构,实现了极高的吞吐量。本文深入解析 Redis 的核心原理,包括数据结构(如 SDS、跳表、哈希表等)、持久化机制(RDB 快照与 AOF 日志)、高并发优化(惰性删除、定期删除)及分布式架构(主从复制、Sentinel、Cluster)。通过合理的缓存策略和数据结构选择,Redis 在高并发系统中表现卓越,为大规模应用提供可靠的存储与加速方案。

whl 博客专栏 3379

基于Simulink的发动机管理系统中的自适应增压控制系统设计

通过上述详细设计步骤,我们成功开发了一个基于Simulink的自适应增压控制系统。该系统不仅能够实时监测和预测发动机的运行状态,动态调整增压压力目标值,还具备实时监控、故障诊断和保护功能,确保系统的安全性和可靠性。此外,通过仿真实验和硬件在环测试,我们验证了系统的性能,并对其进行了优化,使其能够更好地满足实际应用需求。这个项目展示了如何利用MATLAB/Simulink的强大功能,结合控制理论和工程实践,开发出高效、可靠的自适应增压控制系统。

MHD0815的博客 221

【面试】Redis中Bitmap、布隆过滤器和Hypeloglog区别

​Redis中的Bitmap(位图)是一种较为特殊数据类型,它以最小单位bit来存储数据,我们知道一个字节由 8个 bit 组成,和传统数据结构用字节存储相比,这使得它在处理大量二值状态(true、false 或 0、1等只有两种状态)数据时具有极高的空间效率。不过,它不是一种全新的数据类型,其底层实现仍是基于 String 类型。HyperLogLog(HLL)和Bloom Filter(布隆过滤器)是两种常用于大规模数据处理的概率数据结构,它们用于解决不同的问题,并具有不同的特性和应用场景。

精益求精 1094

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

Redis 数据结构原理及其应用场景大解析

跳表:先查第一层找到7 发现 7 的右边是null了,再从7 查第二层,右边是 37 比22 大,再从7下一层,下一个元素是19 ,19小于22,19的下一个是37,还得下一层,下一层的下一个就是22了,找到了。在数据量较小时,采用 ziplist 作为其编码,按 score 有序,当键或值长度过大(64)或个数过多(128)时,转为 skiplist + hashtable 编码,同时采用的理由是。存储数据,设计目标是让数据存储更紧凑,减少碎片开销,节约内存,它的结构如下。...

流楚丶格念的博客 2582

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

Redis中的HyperLogLog以及HyperLogLog原理

Redis中的hyperLogLog数据结构及原理

qq_42581682的博客 4222

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

【Redis】原理

Redis原理摘要 Redis采用高效的数据结构实现其键值存储系统,核心特点包括: RedisObject:所有数据都封装为RedisObject,包含类型、编码方式等元信息。 动态字符串(SDS):优化C语言字符串,支持O(1)长度获取和动态扩容,提供embstr和raw两种编码方式。 整数集合(IntSet):有序存储整数,支持自动类型升级,适用于小型整数集合。 字典(Dict):核心数据结构,采用链地址法解决哈希冲突,支持渐进式rehash以平滑扩容/收缩。 内存管理:通过引用计数和LRU机制实现内存

qq_73127416的博客 1096

【Redis底层原理】之数据结构与持久化机制

Redis 是一个开源的、基于内存的高性能键值存储数据库,它支持多种类型的数据结构。Redis 的数据结构类型和它们的底层实现是 Redis 强大功能和高效性能的基础。

林木森的博客 1170

redis数据结构底层原理——看这一篇就够了

浅识redis 我们说 Redis 相对于 Memcache 等其他的缓存产品,有一个比较明显的优势就是 Redis 不仅仅支持简单的key-value类型的数据,同时还提供list,set,zset,hash等数据结构的存储。通过学习本篇博客的内容,初步了解redis的基本数据结构。本人学识有限,如有错误,及时指出,不胜感激~ 注意:Redis的命令不区分大小写,但是key 严格区分大小写!!! string **介绍 ** String相信大家都很熟悉,不管是Java,C,C++还是python,都有S

GEPEIDUO的博客 1007
上一篇: 延时队列的设计与实现
下一篇: QUIC传输协议设计
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值