老板让我统计页面UV,我用 HyperLogLog三分钟搞定!

点击上方 IT牧场 ,选择 置顶或者星标

技术干货每日送达

redis四两拨千斤-HyperLogLog

UV统计场景

        假设我们有这样的一个场景,需要我们统计一个页面的每天有多少用户访问(UV)。通常情况下我们肯定会想到使用Set集合来存储UserId,Set集合会帮我们把UserId去重,我们直接获取Set的长度就可以了。

    这种方法有一个很大的问题,就是所占用的空间非常的大。假如有100万个用户,我们只存储用户的int类型的UserId,100万 * 4byte / 1024Kb /1024Mb = 3.8G,将近4个G的数据,这还是一天的统计数据,我们就占用了4个G!这种方式绝不可取。那有没有一种既可以完成目前的需求,又可以占用很少空间的方法呢?

        下面祭出Redis的杀手锏HyperLogLog,它是一种数据结构自带去重效果,在Redis中只占用12kb,却可以计算2^62个数(相当于10^14个用户)。值得注意的是,他是一估算值,存在一个小于1%的误差。通常我们统计一个页面的UV的时候不需要特别准确的数据,对于老板老来说105w和106w没什么区别。

基本用法

HyperLogLog只有三个命令使用起来非常简单

  • PFADD

语法:PFADD key val1 val2 val3
pfadd 命令有两个入参,key为redis的key,如果key不存在会自动创建一个,val为数据集的基数,HyperLogLog并不会直接将基数添加到数据集中,而是根据基数来进行估算之前是否遇到过当前的val,具体的估算逻辑还是有些复杂的。

127.0.0.1:6379> pfadd pfkey 1 2 3 3
(integer) 1
127.0.0.1:6379> pfcount pfkey
(integer) 3
  • PFCOUNT

语法:PFCOUNT key
pfcount 命令返回给定 HyperLogLog 的基数估算值。

127.0.0.1:6379> pfcount pfkey
(integer) 3
  • PFMERGE

语法:PFMERGE destkey sourcekey
命令将多个 HyperLogLog 合并为一个 HyperLogLog ,合并后的 HyperLogLog 的基数估算值是通过对所有 给定 HyperLogLog 进行并集计算得出的。

127.0.0.1:6379> pfadd pfkey 1 2 3 3
(integer) 1
127.0.0.1:6379> pfcount pfkey
(integer) 3
127.0.0.1:6379> pfadd pfkey2 1 2 3
(integer) 1
127.0.0.1:6379> pfcount pfkey2
(integer) 3
127.0.0.1:6379> pfmerge pfkey pfkey1
OK
127.0.0.1:6379> pfcount pfkey
(integer) 3

使用案例

简单的java实现

public static void main(String[] args) {
     JedisPool jedisPool = new JedisPool(host,port);
        Jedis jedis = jedisPool.getResource();
        //清空 key
        jedis.del("keypf");
        //循环写入数据
        for (int i = 0; i < 1000; i++) {
            jedis.pfadd("keypf", UUID.randomUUID().toString());
        }
        //获取统计数据
        long pfcount = jedis.pfcount("keypf");
        System.out.println("1000次写入,count的结果="+pfcount);
    }

干货分享

最近将个人学习笔记整理成册,使用PDF分享。关注我,回复如下代码,即可获得百度盘地址,无套路领取!

•001:《Java并发与高并发解决方案》学习笔记;•002:《深入JVM内核——原理、诊断与优化》学习笔记;•003:《Java面试宝典》•004:《Docker开源书》•005:《Kubernetes开源书》•006:《DDD速成(领域驱动设计速成)》•007:全部•008:加技术群讨论

近期热文

LinkedBlockingQueue vs ConcurrentLinkedQueue解读Java 8 中为并发而生的 ConcurrentHashMapRedis性能监控指标汇总最全的DevOps工具集合,再也不怕选型了!微服务架构下,解决数据库跨库查询的一些思路聊聊大厂面试官必问的 MySQL 锁机制

关注我

喜欢就点个"在看"呗^_^

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值