redis的HyperLogLog实战

字节鎏金师
• 阅读 3035

本文主要研究一下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

点赞
收藏
评论区
推荐文章
peter peter
4年前
Go-连接Redis-学习go-redis包
Redis介绍Redis是一个开源的内存数据结构存储,常用作数据库、缓存和消息代理。目前它支持的数据结构有诸如string、hash、list、set、zset、bitmap、hyperloglog、geospatialindex和stream。Redis内置了复制、Lua脚本、LRU清除、事务和不同级别的磁盘持久性,并通过RedisSentinel
Wesley13 Wesley13
3年前
redis的HyperLogLog实战
序本文主要研究一下redis的HyperLogLog的用场相关命令pfadd每添加一个元素的复杂度为O(1)127.0.0.1:6379pfadduv0907uid1uid2uid3(integer)1添加元素到HyperLogLog中,如果内部有变动返回1,没有
Stella981 Stella981
3年前
Redis 列表(List)
Redis列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素导列表的头部(左边)或者尾部(右边)一个列表最多可以包含2321个元素(4294967295,每个列表超过40亿个元素)。实例redis127.0.0.1:6379LPUSHw3ckeyredis(integer)1
Stella981 Stella981
3年前
CentOS7.4 Redis5.0.3配置
本文内容主要包括,以下两个方面:redis的安装及配置redis防入侵的保护措施禁止一些redis高危命令(config,flushall,flushdb,keys)为redis添加密码验证禁止外网访问redis为redis服务创建单独的用户和家目录
Wesley13 Wesley13
3年前
JAVA面试——Redis
1、Redis是什么?都有哪些使用场景?Redis是一个使用C语言开发的高速缓存数据库。Redis使用场景:1)记录帖子点赞数、点击数、评论数;2)缓存近期热帖;3)缓存文章详情信息;4)记录用户会话信息。2、Redis有哪些功能?1)数据缓存功能;2)
Stella981 Stella981
3年前
Nginx + lua +[memcached,redis]
精品案例1、Nginxluamemcached,redis实现网站灰度发布2、分库分表/基于Leaf组件实现的全球唯一ID(非UUID)3、Redis独立数据监控,实现订单超时操作/MQ死信操作SelectPollEpollReactor模型4、分布式任务调试Quartz应用
Stella981 Stella981
3年前
KVM调整cpu和内存
一.修改kvm虚拟机的配置1、virsheditcentos7找到“memory”和“vcpu”标签,将<namecentos7</name<uuid2220a6d1a36a4fbb8523e078b3dfe795</uuid
Stella981 Stella981
3年前
Redis 常见 7 种使用场景
Redis常见7种使用场景(PHP实战)Redis是一个开源的使用ANSIC语言编写、支持网络、可基于内存亦可持久化的日志型、KeyValue数据库,并提供多种语言的API。本篇文章,主要介绍利用PHP使用Redis,主要的应用场景。简单字符串缓存实战$redis
Stella981 Stella981
3年前
Redis命令行之Zset
一、Redis之Zset简介1\.有序集合Zset是String类型的有序集合。2\.Zset中每个元素都会关联一个double类型的分数值,redis通过分数值来为集合中所有成员进行从小到大排序。3\.Zset的成员是唯一的,但分数值可以重复。4\.Zset是通过hash表实现的,添加、删除、查找的复杂度都是O(1)。5
Stella981 Stella981
3年前
Redis哈希对象的ziplist编码实现了O(1)复杂度吗
问题:Redis中哈希对象有两种编码方式,分别是ziplist、hashtable方式。哈希对象,总得体现哈希算法,使得基本操作达到O(1)的效率。hashtable编码方式使用字典,也即是Java中hashMap的方式,这个我可以理解。但是,ziplist方式所有元素都是紧挨的,它是怎么实现hash,并使得查询等操作有O(1)的时间效率的呢?让我们