Redis

Redis之HypeLogLog的使用

2020-06-13  本文已影响0人  AbstractCulture

需求分析

现在一个网站需要统计访问量
那么就会需要两个关键的数据:
网站的浏览量:Page View ,下面简称PV
网站的用户访问数量:User View,下面简称UV

简单的实现PV与UV统计

在Redis的String类型中,提供了一个API为incr key,可以为一个key的value做自增操作,每次调用则自增1。
我们可以将pv视作key,每次网站被点击就自增1,就可以简单的实现PV的统计了。

Redis还有一个Set的数据结构,可以轻松的实现去重的操作,通过sadd key element指令,将uv视作key,不同的用户视作element,每当一个新用户进入网站时,则往set集合中添加一个userId。在需要统计的时候通过scard key指令(时间复杂度为O(1)),则可以得到网站的用户访问数量了.

缺点:当用户量暴增的时候,由于set集合里面存储的是元素值,会耗费大量的空间,而这个数据本身是允许有容错的。得不偿失

为此,Redis提供了另外一种数据结构:HypeLogLog

HypeLogLog

HyperLogLog 是用来做基数统计的算法,HyperLogLog 的优点是,在输入元素的数量或者体积非常非常大时,计算基数所需的空间总是固定 的、并且是很小的。
在 Redis 里面,每个 HyperLogLog 键只需要花费 12 KB 内存,就可以计算接近 2^64 个不同元素的基 数。这和计算基数时,元素越多耗费内存就越多的集合形成鲜明对比。

它提供了几个指令,但是解决UV这个问题,我们只需要用到其中的两个指令即可

pfadd key element|element

统计

pfcount key

下面在Java中模拟数据进行测试,发现结果的准确率是很高的。

package com.xjm.redis;

/**
 * 使用Redis的HyperLogLog统计用户访问量Page View和访问用户数User View
 */
public class CountPvAndUv {
    public static void main(String[] args) {
        Redis redis = new Redis();
        redis.exeute(jedis -> {
            for (int i = 0; i < 2000; i++) {
                //key为uv,value每次放2个,一个是当前的i,一个是下一个i值,那么下次循环就会产生重复值了
                jedis.pfadd("uv","u"+i,"u"+(i+1));
            }
            long uv = jedis.pfcount("uv");
            System.out.println(uv);
        });
    }
}
image.png
上一篇 下一篇

猜你喜欢

热点阅读