UV
UV(Unique Visitor)就是指网站的独立用户访问量Unique Visitor,对相同用户的多次访问需要去重。
考虑到UV需要去重,可能会考虑使用redis的Set。Set里面存储用户的Id。每一个用户访问页面的时候,我们直接把Id存入Set,最终获取Set的size。但是如果用户量上亿的话,存储空间需要非常大。
也可能会考虑使用数据库记录用户请求,但是这样数据库写入量很大,导致数据库压力会比较大。同时如果用户很多,需要的存储空间也非常大。
HyperLogLog
原理
每次将一个字符串放入HyperLogLog,其实是把字符串转换成了一个值,可以把它当成hash值。
将这个值转换成2进制,从后向前看第一个1出现的位置。我们假设为K。那么1出现在第三个位置的时候(xxxx x100),概率是多少呢?(1/2)^3=1/8。也就是大概有八个数字进到这个数据结构时,第一个1 曾出现 在第三个的位置的可能会比较大。
所以我们只需要维护一个1出现位置的最大值(暂且称之为max position),我们就可以知道整个HyperLogLog数量是多少了。
上面讲到hash值,其实整个算法就是将一个固定的value固定的映射成一个数字就可以解决重复的问题了。如“zhangsan”对应8,那么max position=4,再来一个“zhangsan”,对应8,则max position不变。
因为是概率问题,总会出现不准确的情况。所以你在尝试HyperLogLog时,可以将user数量设置大一些,如100W。所以有可能你看到的是不到100W,也有可能计算出来的uv还比100W大。误差在0.81%左右,但是对于统计用户数这种场景来说足够了。
实现
依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<