【Redis】应用场景-统计海量 UV日活(HyperLogLog)

1,概述

在当今数字化时代,对于网站和应用程序的运营者而言,了解其用户的行为和习惯是至关重要的。其中,衡量页面的独立访客数量(UV)是评估网站流量和用户参与度的重要指标之一。然而,当面对海量访问数据时,传统的计数方法可能变得低效且成本高昂。

为解决这一挑战,Redis 提供了一种高效的解决方案:HyperLogLog。HyperLogLog 是一种基数估算算法,能够在常量时间内对集合中不同元素的近似数量进行快速估算。本文就来详细介绍下如何使用 Redis 统计海量 UV。

2,PV、UV 是什么?

PV(Page Views)是页面浏览量,指的是网站或应用程序页面被访问的次数。每一次页面的加载都被视为一个页面浏览量,无论是否为同一用户。

UV(Unique Visitors)是独立访客数量,指的是访问网站或应用程序的唯一用户数量。UV通常用于衡量网站或应用程序的独立用户群体规模,而不考虑他们的访问频率。PV 和 UV 是衡量网站或应用程序流量和用户参与度的重要指标之一。

 3,Hyperloglog算法

HyperLogLog 是一种基数估算算法,可以用于快速计算一个集合中的不同元素数量的近似值。hyperloglog 算法,利用非常少的空间,实现比较大的数据量级统计;比如我们前面在介绍 bitmap 的过程中,说到了日活的统计,当数据量达到百万时,最佳的存储方式是 hyperloglog,

hyperloglog通常是用来非精确的计数统计,当时使用的是 bitmap 来作为数据统计,然而当 userId 分散不均匀,小的特别小,大的特别大的时候,并不适用

在数据量级很大的情况下,hyperloglog的优势非常大,它所占用的存储空间是固定的2^14 下图引用博文《用户日活月活怎么统计》

4,统计原理

在使用 HyperLogLog 统计页面 UV 时,我们可以将每个访问者的 IP 地址作为一个元素加入到 HyperLogLog 中,然后通过计算 HyperLogLog 中元素数量的近似值来估计页面的唯一访问者数量。使用 HyperLogLog 进行日活统计的设计思路比较简单

1,每日生成一个 key,
2,某个用户访问之后,执行 pfadd key userId
3,统计总数: pfcount key

关于 HyperLogLog 的原理我这里也不进行详细赘述,说实话那一套算法以及调和平均公式我自己也没太整明白;下面大致说一下我个人的朴素理解

Redis 中的 HyperLogLog 一共分了2^14=16384个桶,每个桶占 6 个 bit

一个数据,塞入 HyperLogLog 之前,先 hash 一下,得到一个 64 位的二进制数据

取低 14 位,用来定位桶的 index
高 50 位,从低到高数,找到第一个为 1 出现的位置 n若桶中值 > n,则丢掉反之,则设置桶中的值为 n
那么怎么进行计数统计呢?

拿所有桶中的值,代入下面的公式进行计算

5,代码实现

import redis.clients.jedis.Jedis;
​
public class HyperLogLogExample {
    public static void main(String[] args) {
        // 连接 Redis 服务器
        Jedis jedis = new Jedis("localhost");
​
        // 创建一个 HyperLogLog 实例
        String hyperLogLogKey = "unique_users";
        
        // 模拟用户访问行为,向 HyperLogLog 中添加元素
        jedis.pfadd(hyperLogLogKey, "user1", "user2", "user3", "user4");
​
        // 获取 HyperLogLog 的基数估计结果
        long estimatedCount = jedis.pfcount(hyperLogLogKey);
        System.out.println("Estimated unique users: " + estimatedCount);
​
        // 模拟新的用户访问
        jedis.pfadd(hyperLogLogKey, "user5", "user6", "user7");
​
        // 更新基数估计结果
        estimatedCount = jedis.pfcount(hyperLogLogKey);
        System.out.println("Updated estimated unique users: " + estimatedCount);
​
        // 关闭 Redis 连接
        jedis.close();
    }
}

<think>我们正在讨论RedisHyperLogLog相关命令。根据引用内容,HyperLogLogRedis中通过三个命令实现:PFADD、PFCOUNT和PFMERGE。用户要求列出这些命令的详细列表和说明。 引用[1]提到:PFADD用于添加元素,PFCOUNT用于获取基数估计值,PFMERGE用于合并多个HyperLogLog结构。 引用[2]提供了每个命令的简要说明、语法、可用版本和返回值,以及示例的链接(但具体示例内容未显示)。 引用[3]强调了这些命令的时间复杂度为常数时间O(1),即使在大数据集上也很快。 因此,我们可以按照以下结构回答: 1. 列出三个命令,并分别详细说明(语法、返回值、可用版本等)。 2. 提供简单示例(由于引用中没有具体示例,我们可以根据标准用法给出示例)。 3. 总结HyperLogLog命令的特点(如低存储、高效率等)。 注意:引用中提到的命令只有三个,所以列表就是这三个。 另外,用户要求参考他上一次的问题和回答。回顾历史,用户之前询问的是Redis命令重命名为空字符串,但当前问题转向了HyperLogLog的命令列表,两者没有直接关联。因此,我们只需专注于当前问题。 根据引用[2]的目录结构,我们可以这样组织: 命令列表: 1. PFADD 2. PFCOUNT 3. PFMERGE 我们将为每个命令提供: - 简介 - 语法 - 可用版本(根据引用[2]都是>=2.8.9) - 返回值 - 示例(简单示例) 最后,总结HyperLogLog命令的优势。 由于用户要求“尽可能多的参考用户上一次的问题和你的回答”,但上一次是关于命令重命名,而这次是HyperLogLog,两者无关,所以我们只需回答当前问题即可。 注意:引用[1][2][3]都提到了这三个命令,所以我们的回答基于这些引用。 开始回答:</think>### Redis HyperLogLog 相关命令详解 Redis HyperLogLog 是一种概率性数据结构,用于**高效估算海量数据的唯一元素数量(基数)**,仅需 12KB 内存即可处理亿级数据。以下是其核心命令列表及说明: #### 📋 HyperLogLog 命令列表 | 命令 | 语法 | 功能描述 | 时间复杂度 | 返回值 | |-----------|-------------------------------------------|--------------------------------------------------------------------------|------------|----------------------| | **PFADD** | `PFADD key element [element ...]` | 将元素添加到 HyperLogLog 结构中 | $O(1)$ | 若新元素被添加返回 1,否则返回 0 | | **PFCOUNT**| `PFCOUNT key [key ...]` | 估算 HyperLogLog 的基数(唯一元素数量) | $O(1)$ | 整数形式的基数估计值 | | **PFMERGE**| `PFMERGE destkey sourcekey [sourcekey ...]` | 合并多个 HyperLogLog 到目标键中 | $O(N)$ | 成功返回 `OK` | --- #### 1. **PFADD**:添加元素 - **作用**:向指定键的 HyperLogLog 添加元素(如元素已存在则忽略)。 - **示例**: ```bash > PFADD hll_visitor "user_123" "user_456" "user_123" (integer) 1 # 新元素被添加 ``` - 添加成功返回 `1`(至少一个元素是新的),否则返回 `0`[^1][^3]。 #### 2. **PFCOUNT**:基数估算 - **作用**:计算 HyperLogLog 的近似基数(标准误差约 0.81%)。 - **示例**: ```bash > PFCOUNT hll_visitor (integer) 2 # 估算唯一用户数为 2 ``` - 支持多键合并计算:`PFCOUNT hll1 hll2` 返回并集基数[^2]。 #### 3. **PFMERGE**:合并结构 - **作用**:将多个 HyperLogLog 合并到目标键(用于跨数据集统计)。 - **示例**: ```bash > PFMERGE hll_total hll_day1 hll_day2 # 合并两天的数据 OK > PFCOUNT hll_total (integer) 35000 # 估算总唯一用户数 ``` - 合并后目标键存储并集结果[^2]。 --- #### ⚙️ 技术特性 - **内存效率**:固定使用 **12KB** 内存,与数据量无关[^3]。 - **误差范围**:标准误差率 **0.81%**(可配置更低)。 - **适用场景**: - 网站 UV(独立访客)统计 - 大规模志去重分析 - 实时流量监控 > 💡 **注意**:HyperLogLog 是**概率性数据结构**,不存储原始元素,仅提供基数估计。需精确值时应使用 `SET` 或 `HLL` 替代。 --- #### 示例应用:统计用户 ```bash # 添加上午用户 PFADD hll_am "user1" "user2" "user1" # 添加下午用户 PFADD hll_pm "user2" "user3" "user4" # 合并全天数据 PFMERGE hll_daily hll_am hll_pm # 估算用户数 PFCOUNT hll_daily # 返回 ≈4 ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

常生果

喜欢我,请支持我

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值