当前位置: 首页 > ai >正文

【2025最新redis数据结构之Hypeloglog介绍】关于Hypeloglog

HyperLogLog (HLL) 算法深度解析

一、HLL 基本概念

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

核心特点

  • 极低内存消耗:统计 10^9 个不重复元素仅需约 1.5KB 内存

  • 固定大小结构:内存占用与基数大小无关

  • 可合并性:多个 HLL 结构可以合并计算总基数

二、算法实现原理

1. 基本思想

HLL 基于以下观察:在一个随机均匀分布的比特流中,连续出现 "0" 的最大数量 k 与数据集中不重复元素的数量 N 存在关系:N ≈ 2^k

2. 核心组件

  1. 哈希函数

    • 将输入元素映射为足够长的比特串(通常 64 位)

    • 要求:均匀分布、确定性

  2. 分桶(Register)

    • 使用前 m 个比特确定桶索引(m 通常取 12-16)

    • 剩余比特用于计算连续前导零的数量

  3. 调和平均数

    • 用于合并各桶的估算值,减少误差

3. 算法步骤

  1. 初始化

    m = 2^b # b 通常取 4-16 registers = [0] * m

  2. 添加元素

    def add(element):hash = sha1(element).hexdigest()  # 生成哈希值index = int(hash[:b], 16) % m    # 前b位作为桶索引value = hash[b:]                 # 剩余部分计算前导零leading_zeros = count_leading_zeros(value) + 1registers[index] = max(registers[index], leading_zeros)
  3. 估算基数

    def estimate():harmonic_mean = sum(2 ** -r for r in registers) ** -1return alpha * m * m * harmonic_mean  # alpha 为修正因子

三、Redis 中的实现(为什么redis中只占用了12kb的大小)

Redis 实现的 HyperLogLog 使用 16384 (2^14) 个桶,每个桶占 6 bits,总内存占用:

12 KB = 16384 * 6 / 8 / 1024

内存布局

+---------+---------+-----+---------+
| 11000000 | 00011100 | ... | 00101100 |  # 每个桶6位
+---------+---------+-----+---------+

关键命令

PFADD key element [element ...]  # 添加元素
PFCOUNT key [key ...]           # 获取基数估算
PFMERGE destkey sourcekey [sourcekey ...] # 合并多个HLL

四、数学原理深度解析

1. 概率基础

对于均匀分布的哈希值,连续出现 k 个前导零的概率:

P = 1 / 2^(k+1)

2. 估算公式

原始 LogLog 估算:

E = α * m * 2^(1/m * Σρ)

改进的 HyperLogLog 估算:

E = α * m * m / (Σ2^(-ρ))

其中:

  • m = 桶数量

  • ρ = 各桶的最大前导零数

  • α = 修正因子(m=16:0.673, m=32:0.697, m=64:0.709, m≥128:0.7213/(1+1.079/m))

3. 误差修正

对小范围基数进行线性修正:

  • 当 E < 2.5m:使用线性计数

  • 当检测到空桶:调整估算公式

五、性能优化技术

  1. 稀疏表示

    • 对小基数使用显式存储

    • 当基数较小时直接存储元素而非寄存器值

  2. 偏差校正

    • 对小范围基数使用预先计算的校正表

    • 消除系统偏差

  3. 寄存器压缩

    • 使用变长编码压缩寄存器数组

    • 在合并时解压缩处理

六、应用场景

  1. 网站UV统计

    # 统计日UV
    PFADD daily:uv:20230501 user1 user2 user3
    PFCOUNT daily:uv:20230501
  2. 跨日统计

    PFMERGE weekly:uv daily:uv:20230501 daily:uv:20230502 ... daily:uv:20230507
  3. A/B测试

    # 统计不同方案的独立用户数
    PFADD variant:A user1 user3 user5
    PFADD variant:B user2 user3 user6

七、与其他基数统计方案对比

算法内存占用误差率是否精确合并能力
HashSetO(N)0%
Linear CountingO(N)可变
LogLogO(log(logN))1.3/√m
HyperLogLogO(log(logN))0.81/√m
HyperLogLog++O(log(logN))0.81/√m

八、实现注意事项

  1. 哈希函数选择

    • 需要良好的分布特性

    • Redis 使用 64 位 MurmurHash2

  2. 寄存器位数

    • 通常 5-6 位足够(最大前导零 32-64)

    • 更多位数对精度提升有限

  3. 边界情况处理

    • 空数据集返回 0

    • 小数据集使用精确计数

HyperLogLog 通过巧妙的概率统计方法和分桶技术,在极小内存占用下实现了大规模数据集的基数估算,是大数据时代不可或缺的基数统计工具。Redis 的实现进一步优化了内存使用和计算效率,使其成为实际应用中的首选方案。

http://www.xdnf.cn/news/622.html

相关文章:

  • JBoss + WildFly 本地开发环境完全指南
  • 卷积神经网络综述
  • 【重走C++学习之路】14、多态
  • 第二十节:项目经验-描述一个React性能优化案例
  • 21. git apply
  • 时序预测 | Transformer-LSTM-SVM时间序列预测(Matlab完整源码和数据,适合基础小白研究)
  • 《前端面试题之 Vue 篇(第三集)》
  • 【滑动窗口】找到字符串中所有字⺟异位词(medium)
  • 计算机组成原理笔记(十六)——4.1基本算术运算的实现
  • 8、constexpr if、inline、类模版参数推导、lambda的this捕获---c++17
  • 【滑动窗口】串联所有单词的⼦串(hard)
  • 常用的几种 Vue 父子组件传值方式
  • redis+lua脚本
  • 【英语语法】词法---动词
  • hadoop分布式部署
  • Linux `init 5` 相关命令的完整使用指南
  • Android学习总结之APK打包流程
  • 【踩坑记录】Pico串流SteamVR绿屏解决方案:排查兼容性问题与Windows系统升级指南
  • STM32 HAL库FreeRTOS 中断管理
  • XSS学习1之http回顾
  • 【读书笔记·VLSI电路设计方法解密】问题63:为什么可测试性设计对产品的财务成功至关重要
  • 机器学习周报-文献阅读
  • FastAPI-MCP
  • 8节串联锂离子电池组可重构buck-boost均衡拓扑结构 simulink模型仿真
  • 个人所得税
  • DeepSeek R1 7b,Langchain 实现 RAG 知识库 | LLMs
  • 抽象工厂模式及其在自动驾驶中的应用举例(c++代码实现)
  • 秒杀抢购系统架构与优化全解:从业务特性到技术落地
  • tigase源码学习杂记-组件化设计
  • AI预测3D新模型百十个定位预测+胆码预测+去和尾2025年4月20日第58弹