专栏首页码匠的流水账redis的HyperLogLog实战

redis的HyperLogLog实战

本文主要研究一下redis的HyperLogLog的用场

相关命令

pfadd

每添加一个元素的复杂度为O(1)

127.0.0.1:6379> pfadd uv0907 uid1 uid2 uid3
(integer) 1
  • 添加元素到HyperLogLog中,如果内部有变动返回1,没有返回0

pfcount

作用域单个HyperLogLog时,复杂度为O(1),作用于多个HyperLogLog时,复杂度为O(N)

127.0.0.1:6379> pfcount uv0907
(integer) 3
  • 返回该HyperLogLog的近似基数,如果是指定多个HyperLogLog则返回的是他们的并集的近似基数

pfmerge

复杂度为O(N),N为合并后的HyperLogLog数量

127.0.0.1:6379> pfadd uv0906 uid1 uid4 uid5
(integer) 1
127.0.0.1:6379> pfmerge uv0607 uv0906 uv0907
OK
127.0.0.1:6379> pfcount uv0607
(integer) 5
  • 合并指定的HyperLogLog到新的HyperLogLog中

使用场景

HyperLogLog是Probabilistic data Structures的一种,这类数据结构的基本大的思路就是使用统计概率上的算法,牺牲数据的精准性来节省内存的占用空间及提升相关操作的性能。最典型的使用场景就是统计网站的每日UV。实例如下:

    @Test
    public void testUv(){
        String uv1 = "uv96";
        String uv2 = "uv97";
        IntStream.rangeClosed(1,100)
                .forEach(i -> {
                    System.out.println(i);
                    redisTemplate.opsForHyperLogLog()
                            .add(uv1,"user"+i);
                    redisTemplate.opsForHyperLogLog()
                            .add(uv2,"user"+i/2);
                });

        long uv1Count = redisTemplate.opsForHyperLogLog().size(uv1);
        System.out.println(uv1Count);
        long uv2Count = redisTemplate.opsForHyperLogLog().size(uv2);
        System.out.println(uv2Count);

        String uv1uv2 = "uv67";
        Long uv1uv2Count = redisTemplate.opsForHyperLogLog().union(uv1uv2,uv1,uv2);
        System.out.println(uv1uv2Count);
        Long realCount = redisTemplate.opsForHyperLogLog().size(uv1uv2);
        System.out.println(realCount);
    }

小结

  • redis的HyperLogLog特别是适合用来对海量数据进行unique统计,对内存占用有要求,而且还能够接受一定的错误率的场景。
  • 对于union操作由于是O(N),在海量数据层面需要注意慢查询问题。

doc

  • hyperloglog
  • pfadd
  • pfcount
  • pfmerge
  • HyperLogLogs in Redis
  • hyperloglog的java版使用

本文分享自微信公众号 - 码匠的流水账(geek_luandun)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2018-09-07

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • spring基础(1:基本概念)

    本系列笔记来自对《Spring实战》第三版的整理,Spring版本为3.0   spring是为了解决企业级应用开发的复杂性而创建的,spring最根本的...

    用户2038589
  • springboot整合mybatis(xml+注解)

    ​ 刚毕业的第一份工作是java开发,项目中需要用到mybatis,特此记录学习过程,这只是一个简单demo,mybatis用法很多不可能全部写出来,有更复杂的...

    用户2038589
  • APP概括

    移动端:运行在移动设备上的产品 移动设备:手机 平板 我们做的页面只适用于安卓系统和ios系统,诺基亚是Windows Phone系统不用管

    河湾欢儿
  • 我是怎样一步步加入程序员大军

    对于文章所描写的那样,程序员是一群一年四季只有衬衫,短裤,拖鞋,电脑包,黑色眼睛的一群高薪繁忙的单身狗。

    君赏
  • CentOS安装配置

    用户3004328
  • 组件&生命周期

    组件使你可以将 UI 划分为一个一个独立,可复用的小部件,并可以对每个部件进行单独的设计。

    河湾欢儿
  • React入门

    React 是一个用于构建用户界面的 JAVASCRIPT 库。 起源: React 起源于 Facebook 的内部项目,因为该公司对市场上所有 Java...

    河湾欢儿
  • 如何更改github工程的语言属性

    当创建github项目的时候,github本身会根据提交文件的数量来自动推断工程的开发语言,有时这种推断结果会与实际情况不太相符。

    Python疯子
  • Require.js

    通过require.js 可以对javascript文件进行别样引用 Require.js的使用: 第一步: 只需在html页面中引用require.js ...

    河湾欢儿
  • JavaScript简单介绍

    基于事件和对象驱动,并具有安全性的语言。 该语言运行在浏览器端,也有在服务器端的名称为Node.js

    河湾欢儿

扫码关注云+社区

领取腾讯云代金券