15、HyperLogLog统计基数

学习目标:

1、了解HyperLogLog作用

2、掌握redis对HyperLogLog的命令的支持

学习过程:

一、了解HyperLogLog算法

基数估算时大数据应用场景中最常见的一应用,比如如果我们需要统计一天内的独立用户数,一个用户在可能会多次的访问,但是我们不需要重复的累计,最后统计的数量只要误差不太大就行了,那么我们是否需要记录每一个用户呢,事实上我们需要获得的时用户数即可,如果有几十亿用户,全部记录起来再统计,不仅会耗费大量的储存空间,也会影响统计的效率。

HyperLogLog 时一种基数统计的算法,在输入元素的数量或者体积非常非常大时,计算基数所需的空间总是固定的、并且是很小的,redis每一个HyperLogLog元素最多就是12K,HyperLogLog只会根据输入元素来计算基数,而不会储存输入元素本身,所以 HyperLogLog 不能返回输入的各个元素。

HyperLogLog 算法给出的基数并不是精确的,可能会比实际稍微多一些或者稍微少一些,但会控制在合理的范围之内。

二、命令的使用

redis对HyperLogLog算法的支持也非常简单,一般也就是三个命令

pfadd  、 pfcount   、 pfmerge

127.0.0.1:6379> pfadd uname liu  #添加一个进去
(integer) 1
127.0.0.1:6379> pfadd uname bao
(integer) 1
127.0.0.1:6379> pfcount uname  #执行统计
(integer) 2
127.0.0.1:6379> pfadd cname liu  #另外一个HyperLogLog元素,包含和uname一样的liu的值
(integer) 1
127.0.0.1:6379> pfadd cname hello
(integer) 1
127.0.0.1:6379> pfcount cname
(integer) 2
127.0.0.1:6379> pfmerge uname cname  # 合并
OK
127.0.0.1:6379> pfcount uname #在统计
(integer) 3

 

看着上面的数量好像也是挺准确的,我们使用java代码添加更多的数量尝试一下,Java代码如下:

@Test
public void testHyperLogLogSet(){

    HyperLogLogOperations vo = template.opsForHyperLogLog();
   
    
    for (int i = 0; i < 10000; i++) {
    	vo.add("books", "a"+i,"b"+i,"c"+i); 
    }
    
    for (int i = 0; i < 10000; i++) {
    	vo.add("desks", "a"+i,"b"+i,"c"+i); 
    }
}

@Test 
public void testHyperLogLogCount(){ 
    HyperLogLogOperations vo = template.opsForHyperLogLog(); 
    System.out.println("books="+vo.size("books"));
    System.out.println("desks="+vo.size("desks"));

    vo.union("alls","books", "desks"); 

    System.out.println("alls="+vo.size("alls"));
} 

最后输出如下:

books=30067
desks=30067
alls=30067

可以看到并不是30000,还是会有点偏差的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值