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

Redis - Hyperloglog类型

Hyperloglog

用来估算集合中的元素个数!


Set 有一个应用场景:统计服务器的 UV(用户访问的次数)。

使用 Set 当然可以统计 UV,但是最大的问题在于,如果 UV 数据量非常大,Set 就会消耗很多的内存空间:

  • 假设 Set 存储 userId,每个 userId 按照 8 个字节算
  • 1 亿 UV => 8 亿字节 ➡️ 0.8G => 800MB

之所以消耗这么大的空间,是因为 Set 需要存储每个元素。

➡️ HyperLogLog 可以最多使用 12KB 空间,实现上述效果。

  • HyperLogLog 不存储元素的内容
  • 但能够记录 “元素的特征”,从而在新增元素时,判断该元素是已存在还是首次出现
  • 用于计数(记录当前集合中不同元素的数量)
  • 无法获取具体元素内容

Redis HyperLogLog 是一种用于高效统计集合中不重复元素数量(基数)的数据结构,它以极小的内存消耗(约 12KB)实现对海量数据的基数估算,非常适合需要进行去重计数但不需要精确结果的场景。

🔍 核心特性与概念

HyperLogLog 的设计围绕 “基数估算” 问题,关键特性如下:

  • 空间效率:无论统计的元素数量是多少(从几个到数十亿),单个 HyperLogLog 键仅占用约 12KB 内存。
  • 估算精度:存在约 0.81% 的标准误差,但对于大多数业务场景(如 UV 统计)已足够。
  • 合并操作:支持多个 HyperLogLog 集合的合并,可快速计算总基数。
  • 不存储原始数据:仅记录估算基数所需的统计信息,无法恢复原始元素。
  • 核心思路:位操作

📝 核心命令分类(附 C++ 示例)

以下示例基于 hiredis 客户端,需先安装依赖(sudo apt install libhiredis-dev)。

基础操作(添加与统计)
命令功能Redis 命令格式C++ 代码示例
添加元素到集合PFADD key element [element ...]向 user_visits 添加多个用户 ID(如 UV 统计)
估算基数(不重复元素数)PFCOUNT key [key ...]计算 user_visits 中的不重复用户数
合并多个 HyperLogLogPFMERGE destkey sourcekey [sourcekey ...]将多个集合的基数合并到新集合,用于计算总基数(如多天 UV 合并)

代码示例:用户访问量统计

#include <hiredis/hiredis.h>
#include <iostream>
#include <string>
using namespace std;int main() {// 1. 连接 RedisredisContext* ctx = redisConnect("127.0.0.1", 6379);if (ctx->err) {cerr << "连接失败: " << ctx->errstr << endl;return 1;}// 2. 添加访问用户(PFADD user_visits 1001 1002 1003 1001 1004)// 注意:1001 重复添加,但只会被统计一次redisReply* reply = (redisReply*)redisCommand(ctx, "PFADD user_visits 1001 1002 1003 1001 1004");cout << "添加成功(1=成功,0=失败): " << reply->integer << endl; // 输出 1freeReplyObject(reply);// 3. 估算不重复用户数(PFCOUNT user_visits)reply = (redisReply*)redisCommand(ctx, "PFCOUNT user_visits");cout << "估算不重复用户数: " << reply->integer << endl; // 理论结果应为 4(误差范围内)freeReplyObject(reply);// 4. 合并多天数据(如合并 10 月 1 日和 10 月 2 日的 UV)// 先添加 10 月 2 日的用户(void)redisCommand(ctx, "PFADD user_visits_1002 1003 1005 1006");// 合并到 user_visits_totalreply = (redisReply*)redisCommand(ctx, "PFMERGE user_visits_total user_visits user_visits_1002");cout << "合并结果(1=成功): " << reply->integer << endl; // 输出 1freeReplyObject(reply);// 5. 计算合并后的总 UVreply = (redisReply*)redisCommand(ctx, "PFCOUNT user_visits_total");cout << "两天合并后的估算 UV: " << reply->integer << endl; // 理论结果应为 6(误差范围内)freeReplyObject(reply);// 6. 断开连接redisFree(ctx);return 0;
}

🎯 典型应用场景

HyperLogLog 适合需要 去重计数但可接受一定误差 的场景,具体包括:

网站 / APP 访问统计(UV)

  • 统计每日 / 每月访问网站的独立用户数,无需存储用户 ID 列表,12KB 即可支持上亿用户的统计。
  • 优势:相比 Set 类型(存储所有用户 ID),内存占用极低,尤其适合大数据量场景。

搜索关键词去重

  • 统计用户搜索过的不重复关键词数量,分析用户兴趣分布,无需精确记录每个关键词。

数据埋点与分析

  • 统计某个按钮的独立点击用户数、某篇文章的独立阅读用户数等,轻量且高效。

合并统计场景

  • 合并多天、多渠道的 UV 数据(如合并 PC 端和移动端的总 UV),通过 PFMERGE 快速实现。

📌 C++ 开发注意事项

  1. 精度权衡:明确业务是否接受 0.81% 的误差,高精度场景(如财务数据)需使用 Set 或 Hash 替代。
  2. 元素类型PFADD 接受字符串类型的元素,数值需转换为字符串(如示例中的用户 ID)。
  3. 内存占用:单个 HyperLogLog 固定占用约 12KB,与元素数量无关,适合海量数据。
  4. 合并操作PFMERGE 的结果是一个新的 HyperLogLog,源数据不会被修改。
  5. 错误处理hiredis 操作后需检查返回值类型(如 redisReply->type)和上下文错误(ctx->err)。
http://www.dtcms.com/a/407243.html

相关文章:

  • 配置 Oracle Linux 8 仓库为 yum 源
  • 移动网站建设优势滁州公司做网站
  • 用网站模板 侵权 做了修改seo优化提升排名
  • Golang语言基础篇008_接口详解
  • 广州网站设计总部找北京赛车网站开发
  • 做网站需要会哪些计算机语言大学生实训网站建设心得
  • 2025全新的软件测试面试八股文(含答案+文档)
  • 制作网站的步骤域名省住房和城乡建设厅官方网站
  • 做薪酬调查有哪些网站公司域名注册注意事项
  • Spring AI: 为Java开发者赋能的AI工程框架
  • 网站建设制作费 税前扣除吗网站怎么显示建设中
  • 台州专业做网站西安模板建站公司
  • 【项目】Celery:构建高可用分布式任务队列系统
  • 《道德经》第二章
  • 线性复杂度找回文串?Manacher马拉车----字符串算法
  • 品牌服装网站源码做一个网站需要多久
  • 网站描述怎样写微信静首页制作代码
  • JavaScript--基础ES(一)
  • 滚柱直线导轨精度、寿命与成本能否实现三重标准?
  • 室内设计资源网搜外网 seo教程
  • wordpress 移动站如何做网站的图片滑动块
  • 实现当前登录在线人数统计
  • Centos7.9 单机安装OceanBase 社区版
  • 【STM32】USART串口(下)
  • AI 原生应用:重构内容创作的 “智能工厂” 革命
  • 桐乡住房和城乡规划建设局网站i深圳网站建设
  • 安装Neo4j5.26.12社区版本(2025年)
  • Python项目--交互式VR教育应用开发
  • 使用Comate全栈开发一个Python学习网站
  • 网站推广软件工具百度竞价被换着ip点击