<返回更多

基于Redis的HyperLogLog实现访客量统计

2023-08-25  微信公众号  程序猿小杨
加入收藏

一、简介

  我们先思考一个常见的业务问题:如果你负责开发维护一个大型的网站,有一天老板找产品经理要某个网站每个网页每天的 UV(访客量) 数据,然后让你来开发这个统计模块,你会如何实现?

  如果统计 PV(浏览量)那非常好办,给每个网页一个独立的 redis 计数器就可以了,这个计数器的 key 后缀加上当天的日期。这样来一个请求,incrby 一次,最终就可以统计出所有的 PV 数据。

      但是 UV 不一样,它要去重,同一个用户一天之内的多次访问请求只能计数一次。这就要求每一个网页请求都需要带上用户的 ID,无论是登录用户还是未登录用户都需要一个唯一 ID 来标识。

解决方案:Redis 提供了 HyperLogLog 数据结构就是用来解决这种统计问题的。HyperLogLog 提供不精确的去重计数方案,虽然不精确但是也不是非常不精确,标准误差是 0.81%,这样的精确度已经可以满足上面的 UV 统计需求了。

      HyperLogLog 数据结构是 Redis 的高级数据结构,它非常有用,但是令人感到意外的是,使用过它的人非常少。

二、HyperLogLog用法

具体代码:

edis6.3:0>pfadd pf1 p1 p2 p3 p4"1"redis6.3:0>pfcount pf1"4"redis6.3:0>pfadd pf1 p3 p5 p6"1"redis6.3:0>pfcount pf1

pfmerge的用法:

      HyperLogLog 除了上面的 pfadd 和 pfcount 之外,还提供了第三个指令 pfmerge,用于将多个 pf 计数值累加在一起形成一个新的 pf 值。比如:在网站中我们有两个内容差不多的页面,运营说需要这两个页面的数据进行合并。其中页面的 UV 访问量也需要合并,那这个时候 pfmerge 就可以派上用场了。

27.0.0.1:6379> pfmerge user2 user  //将user中的数据合并到user2中OK127.0.0.1:6379> pfcount user(integer) 2

三、实现案例

核心代码:

 public Result testHyperLogLog(){        String[] values = new String[1000];        int j = 0;        for (int i = 0; i < 1000000; i++) {            j = i % 1000;            values[j] = "user_" + i;            if(j == 999){                // 发送到Redis                stringRedisTemplate.opsForHyperLogLog().add("hll", values);            }        }        // 统计数量        Long count = stringRedisTemplate.opsForHyperLogLog().size("hll");        log.info("统计的用户数量count:"+count);        return Result.ok();    }

结果展示:

      100万条数据,统计出来有997461,误差是0.253%,小于标准误差是 0.81%,对于UV 统计需求来说,误差率也不算高,然后我们把上面的脚本再跑一遍,也就相当于将数据重复加入一遍,查看输出,可以发现,pfcount 的结果没有任何改变,还是 997461,说明它确实具备去重功能。

四、注意事项

        HyperLogLog 这个数据结构不是免费的,不是说使用这个数据结构要花钱,它需要占据一定 12k 的存储空间,所以它不适合统计单个用户相关的数据。如果你的用户上亿,可以算算,这个空间成本是非常惊人的。但是相比 set 存储方案,HyperLogLog 所使用的空间那真是可以使用千斤对比四两来形容了。不过你也不必过于担心,因为 Redis 对 HyperLogLog 的存储进行了优化,在计数比较小时,它的存储空间采用稀疏矩阵存储,空间占用很小,仅仅在计数慢慢变大,稀疏矩阵占用空间渐渐超过了阈值时才会一次性转变成稠密矩阵,才会占用 12k 的空间。

五、源码获取方式

     更多优秀文章,请关注个人微信公众号或搜索“程序猿小杨”查阅。然后回复:源码,可以获取该项目对应的源码及表结构,开箱即可使用。

说明:后面redis相关操作的功能都会放在此文件夹中,需要相关功能的,只需要获取最新的资源,替换项目即可

关键词:Redis      点击(18)
声明:本站部分内容来自互联网,如有版权侵犯或其他问题请与我们联系,我们将立即删除或处理。
▍相关推荐
更多Redis相关>>>