【Java-Redis】Redis 如何统计独立用户访问量?

在这里插入图片描述

Java面试题:Redis统计独立用户访问量

题目描述

请使用Redis设计一个统计网站独立用户访问量(UV)的方案,要求:

  1. 支持每日/每月UV统计
  2. 内存占用高效(百万级用户)
  3. 说明Java代码如何调用Redis实现

通俗解答(含故事举例)

假设你开了一家"程序员咖啡店",每天需要统计有多少不同的顾客光顾(排除重复进店的人)。

🌰 故事场景
  • 周一:顾客A、B、C来访
  • 周二:顾客A、D来访
  • 真实UV = 4人(A/B/C/D)

如果用普通计数器:

  • 记录所有顾客ID → 内存爆炸 💥
  • 查重效率低 → 影响咖啡机响应速度 ☕

Redis解决方案:HyperLogLog

Redis的HyperLogLog(HLL)是专门解决这类问题的神器!
特点:

  1. 固定12KB内存,可统计亿级数据
  2. 误差仅0.81%
  3. 支持合并统计(如:月UV = 每日UV合并)
📊 Redis核心命令
# 添加用户访问
PFADD uv:20250806 "userA" "userB"  

# 获取当日UV
PFCOUNT uv:20250806  # 返回2

# 合并多日数据(自动去重)
PFMERGE uv:month_08 uv:20250806 uv:20250807

Java代码实现

import redis.clients.jedis.Jedis;

public class UVCounter {
    public static void main(String[] args) {
        try (Jedis jedis = new Jedis("localhost", 6379)) {
            // 1. 模拟用户访问
            String todayKey = "uv:" + LocalDate.now(); // 例如:uv:2025-08-06
            jedis.pfadd(todayKey, "user123", "user456", "user123"); // user123只计1次
            
            // 2. 获取当日UV
            Long dailyUV = jedis.pfcount(todayKey);
            System.out.println("今日UV: " + dailyUV); // 输出2
            
            // 3. 合并为月统计(每月1日执行)
            String monthKey = "uv:month_202508";
            jedis.pfmerge(monthKey, "uv:20250801", "uv:20250802", todayKey); 
        }
    }
}
🔑 关键点
  1. 去重原理:HLL用概率算法估算基数(类似"抛硬币估算人数"🎲)
  2. 高性能:添加/查询时间复杂度都是 O(1)
  3. 适用场景:点击流统计、DAU/MAU报表

🌟 总结

方案内存占用精度适用规模
Set存ID高(O(n))100%小规模
HLL极低(12KB)99.19%海量数据

优先选择HyperLogLog:在容忍微小误差时,它是内存和性能的最佳平衡。


思维导图

在这里插入图片描述

图:HyperLogLog工作原理示意图

以上内容由AI搜集并生成,仅供参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Java自学之旅

你的鼓励是我最大的动力

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

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

打赏作者

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

抵扣说明:

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

余额充值