欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

HyperLogLog 命令详解

程序员文章站 2022-03-05 14:29:12
...

HyperLogLog 命令详解

HyperLogLog 目前只支持3个命令,PFADD、PFCOUNT、PFMERGE

PFADD

将元素加入到HyperLogLog数据结构中,如果 HyperLogLog 的基数估算值在命令执行之后出现了变化,那么命令返回1,否则返回0。

PFCOUNT

返回给定 HyperLogLog 的基数估算值。

127.0.0.1:6379> pfadd uv 192.168.1.100 192.168.1.101 192.168.1.102 192.168.1.103
(integer) 1
127.0.0.1:6379> pfadd uv 192.168.1.100
(integer) 0
127.0.0.1:6379> pfcount uv
(integer) 4

PFMERGE

把多个HyperLogLog合并为一个HyperLogLog,合并后的HyperLogLog的基数是通过所有的HyperLogLog进行并集后,得出来的。

127.0.0.1:6379> pfadd uv1 192.168.1.100 192.168.1.101 192.168.1.102 192.168.1.103
(integer) 1
127.0.0.1:6379> pfcount uv1
(integer) 4
127.0.0.1:6379> pfadd uv2 192.168.1.100 192.168.2.101 192.168.2.102 192.168.2.103
(integer) 1
127.0.0.1:6379> pfadd uv3 192.168.1.100 192.168.3.101 192.168.3.102 192.168.3.103
(integer) 1
127.0.0.1:6379> pfmerge aganuv uv1 uv2 uv3
OK
127.0.0.1:6379> pfcount aganuv
(integer) 10

这个命令很重要,例如你可以统计一周 或 一个月的uv 就可以使用此命令来轻易实现。

3.案例实战:基于Redis的UV计算

步骤1:模拟UV访问

@Service
@Slf4j
public class TaskService {

    @Autowired
    private RedisTemplate redisTemplate;

    /**
     *模拟UV访问
     */
    @PostConstruct
    public void init(){
        log.info("模拟UV访问 ..........");
        new Thread(()->this.refreshData()).start();
    }

    /**
     * 刷新当天的统计数据
     */
    public void refreshDay(){
        Random rand = new Random();
        String ip=rand.nextInt(999)+"."+
                rand.nextInt(999)+"."+
                rand.nextInt(999)+"."+
                rand.nextInt(999);

        //redis 命令 pfadd
        long n=this.redisTemplate.opsForHyperLogLog().add(Constants.PV_KEY,ip);
        log.debug("ip={} , returen={}",ip,n);
    }

    /**
     * 按天模拟UV统计
     */
    public void refreshData(){
        while (true){
            this.refreshDay();
            //TODO 在分布式系统中,建议用xxljob来实现定时
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

}

步骤2:实现UV统计功能

@RestController
@Slf4j
public class Controller {

    @Autowired
    private RedisTemplate redisTemplate;


    @GetMapping(value = "/uv")
    public long uv() {
        //redis命令 pfcount
        long size=this.redisTemplate.opsForHyperLogLog().size(Constants.PV_KEY);
        return size;
    }

}
相关标签: redis