Redis-UV统计(HyperLogLog)
目录
HyperLogLog
实现UV统计
HyperLogLog
首先我们搞懂两个概念:
UV:全称Unique Visitor,也叫独立访客量,是指通过互联网访问、浏览这个网页的自然人。1天内同一个用户多次访问该网站,只记录1次,就比如说QQ,抖音的访客。
PV:全称Page View,也叫页面访问量或点击量,用户每访问网站的一个页面,记录1次PV,用户多次打开页面,则记录多次PV。往往用来衡量网站的流量。类似于抖音的点赞量。
通常情况下,PV(页面访问量)的数量会大于 UV(独立访客量),所以衡量同一个网站的访问量,我们需要综合考虑很多因素,所以我们只是单纯的把这两个值作为一个参考值
UV统计在服务端做会比较麻烦,因为要判断该用户是否已经统计过了,需要将统计过的用户信息保存。但是如果每个访问的用户都保存到Redis中,数据量会非常恐怖,那怎么处理呢?
Hyperloglog(HLL)是从Loglog算法派生的概率算法,用于确定非常大的集合的基数,而不需要存储其所有值。Redis中的HLL是基于string结构实现的,单个HLL的内存永远小于16kb,内存占用低的令人发指!作为代价,其测量结果是概率性的,有小于0.81%的误差。不过对于UV统计来说,这完全可以忽略。
常见指令:
实现UV统计
因为我们系统的账号较少,无法统计出效果,所以在这里我们通过测试方法实现,代码如下:
@Testvoid testHyperLogLog() {// 准备数组,装用户数据String[] users = new String[1000];// 数组角标int index = 0;for (int i = 1; i <= 1000000; i++) {// 赋值users[index++] = "user_" + i;// 每1000条发送一次if (i % 1000 == 0) {index = 0;stringRedisTemplate.opsForHyperLogLog().add("hll1", users);}}// 统计数量Long size = stringRedisTemplate.opsForHyperLogLog().size("hll1");System.out.println("size = " + size);}
测试:
先查看方法执行前Redis的内存情况:
然后执行方法:
再次查看Redis的内存:
用计算器计算结果:
(新内存大小-旧内存大小)/1024=14.296875kb,符合不大于16kb的内存占用。
在实际开发中,我们经常用HyperLogLog来统计用户的访问量。