Ah! 光を追いかけてきたんだよ… 啊NMD这么多天终于把Redis实战的光追完了
UV统计
UV
搞懂两个概念:
UV:全称
Unique Visitor,也叫独立访客量,是指通过互联网访问、浏览这个网页的自然人。1天内同一个用户多次访问该网站,只记录1次。
PV:全称Page View,也叫页面访问量或点击量,用户每访问网站的一个页面,记录1次PV,用户多次打开页面,则记录多次PV。往往用来衡量网站的流量。
可以预见的是,UV统计在服务端做会比较麻烦,因为要判断该用户是否已经统计过了,需要将统计过的用户信息保存。但是如果每个访问的用户都保存到Redis中,数据量会非常恐怖。
Hyperloglog
Hyperloglog(HLL)是从Loglog算法派生的概率算法,用于确定非常大的集合的基数,而不需要存储其所有值。
Redis中的HLL是基于string结构实现的,单个HLL的内存永远小于16kb,内存占用低的令人发指。作为代价,其测量结果是概率性的,有小于0.81%的误差。不过对于UV统计来说,这完全可以忽略。
对应Redis的操作指令:
PFADD:向指定key中插入元素
PFCOUNT:统计指定key中元素数量(可能会存在误差)
PFMERGE:合并多个key到一个指定key中
-- 插入元素
PFADD key element [element ...]-- 统计元素数量
PFCOUNT key [key ...]-- 合并
PFMERGE destkey sourcekey [sourcekey ...]


查看其内部发现其不记录实际值,只记录大小

实现UV统计
通过向Redis中插入1000w条数据并进行HLL操作来模拟UV统计,以此评估其内存性能
测试之前的内存大小

测试代码如下:
@Test
public void TestHyperLogLog() {String[] values = new String[5000];for(int i=0;i<10000000;++i) {values[i%5000] = "user_"+i;if(i%5000==4999) {stringRedisTemplate.opsForHyperLogLog().add("TestHyperLogLog",values);}}Long SizeCount = stringRedisTemplate.opsForHyperLogLog().size("TestHyperLogLog");System.out.println("Now Size is "+SizeCount);
}
可以看到误差并不大

测试完的内存大小,内存增长了976256−961856=14400Byte,也就是1414.0625KB,内存消耗可观

僕たちはひとつの光 我们是合而为一的光芒

