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

STM32F103新手必看:0.96寸OLED屏幕从接线到动态显示全攻略(附IIC避坑指南)

本文为STM32F103新手提供了0.96寸OLED屏幕从硬件接线到软件驱动的完整实战指南。重点解析了IIC通信的时序、设备地址(0x78/0x7A)的常见陷阱,并详细演示了如何实现字符显示与平滑滚动显示等动态效果,帮助开发者快速上手并避开常见调试难题。

stone的博客 556

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

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

gwndjsh的博客 1026

UE5 Compute Shader实战:从基础到高级应用全解析

本文全面解析了在UE5中应用Compute Shader的完整流程,从基础概念、环境搭建到核心机制与实战应用。详细介绍了如何通过参数传递、线程派遣与数据读写实现GPU并行计算,并深入探讨了GPU粒子模拟、性能优化及结合光线追踪等高级应用场景,为开发者掌握UE5高性能计算提供系统指导。

yhn45678901的博客 501

Redis 数据结构详解

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

一名后端程序猿 8035

医疗影像技术实战:如何用Python快速生成DRR图像(附完整代码)

本文详细介绍了如何使用Python实现数字重建放射影像的快速生成。通过实战代码,从基础光线投射算法到性能优化,逐步讲解DRR图像生成的核心原理与工程实践,帮助开发者掌握医疗影像处理的关键技术,赋能放射治疗规划与图像引导手术等临床工具开发。

k8l9m0n的博客 72

ComfyUI+minimaxh3本地部署:漫剧分镜批量生成工作流全实操

视频生成模型正从云端API向本地化部署迁移,背后的技术逻辑是将扩散模型的文本编码、潜空间采样、VAE解码等阶段拆分为可编排的独立环节。ComfyUI作为节点化管线工具,恰好能以可视化连线方式管理这些阶段,让生成过程可控、可复用、可批量执行。minimaxh3模型支持本地推理,配合LoRA微调与参数优化,能够在保证角色一致性的前提下,从分镜脚本批量产出连续剧情片段,规避云端排队、成本高、素材不可控等工程问题。这套工作流广泛应用于漫剧、短剧和动态条漫的工业化生产,尤其适合需要高频迭代分镜草稿的内容团队。文本以零

weixin_29057065的博客 367

Redis数据结构——HyperLogLog 原理

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

NoviceZ的博客 406

解锁RK3588:内核模块签名与安全启动配置全攻略

RK3588作为一款高性能嵌入式SoC芯片,其内核模块签名与安全启动配置是保障系统安全的核心机制。本文详细介绍了RK3588的芯片特性,重点阐述了安全启动的硬件信任链原理和内核模块签名的实现方法。通过具体步骤演示了从密钥生成、模块签名到验证加载的完整流程,并深入解析了安全启动配置的硬件连接、软件工具准备、密钥烧录等关键环节。此外,还提出了防御旁路攻击和动态信任链扩展等高级安全策略,为RK3588在工业控制、智能安防等高安全要求场景中的应用提供了全面的安全解决方案。

远程部署调试 运行安装 项目调试 二次开发 项目技术新 持续迭代 部分源码免费分享 348

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

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

MarkerHub的博客 701

Android oom_adj 更新原理(一)

通过之前的两篇博文《lmkd 机制详解》和《lmkd中adj score的算法剖析》中,根据计算出来的 min_score_adj 选择大于该值的 oom_adj 的进程进行 kill 处理。oom_adj 随着应用状态的不同其值也是伴随着变化的。本文将通过源码剖析 oom_adj 更新的原理。

私房菜 2655

YOLO11涨点优化:训练技巧 | 使用标签平滑(Label Smoothing)配合余弦退火学习率,防止过拟合,稳步提点

摘要: YOLO11凭借动态卷积核调度、自适应特征融合等创新成为2026年目标检测主流,但面临训练集过拟合问题。文章聚焦两种零推理开销的正则化技巧:标签平滑(Label Smoothing)和余弦退火学习率(Cosine Annealing LR)。标签平滑通过软化硬标签(如将[1,0]改为[0.9,0.1])防止模型过度自信,代码中通过label_smoothing=0.1一键启用;余弦退火则以平滑的余弦曲线调整学习率(cos_lr=True),避免阶梯衰减的震荡。两者组合可显著缩小YOLO11训练与验证

2601_95807009的博客 45

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

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

whl 博客专栏 3379

火灾图像检测识别:cnn卷积神经网络 Adaboost 支持向量机 随机森林 决策树 完整代码数据

火灾图像检测识别:cnn卷积神经网络 Adaboost 支持向量机 随机森林 决策树 完整代码数据

864

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

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

精益求精 1094

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

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

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

流楚丶格念的博客 2582

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

Redis中的HyperLogLog以及HyperLogLog原理

Redis中的hyperLogLog数据结构及原理

qq_42581682的博客 4222

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

【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、付费专栏及课程。

余额充值