• redis HyperLogLog数据类型——亿级用户访问量统计解决方案


    写在前面

    我们可能会遇到这样一个统计场景:基数统计。

    基数统计就是指统计一个集合中不重复的元素个数。比如说统计网页的 UV(访问用户量)。

    网页 UV 的统计有个独特的地方,就是需要去重,一个用户一天内的多次访问只能算作一次。在 Redis 的集合类型中,Set 类型默认支持去重,所以看到有去重需求时,我们可能第一时间就会想到用 Set 类型。

    但是!如果一个网站用户数非常多,使用set类型来记录用户数,会造成大量的内存浪费。而HyperLogLog可以很好的满足这个要求。

    Redis HyperLogLog 是用来做基数统计的算法,HyperLogLog 的优点是,在输入元素的数量或者体积非常非常大时,计算基数所需的空间总是固定 的、并且是很小的。

    在 Redis 里面,每个 HyperLogLog 键只需要花费 12 KB 内存,就可以计算接近 2^64 个不同元素的基 数。这和计算基数时,元素越多耗费内存就越多的集合形成鲜明对比。

    但是,因为 HyperLogLog 只会根据输入元素来计算基数,而不会储存输入元素本身,所以 HyperLogLog 不能像集合那样,返回输入的各个元素。

    HyperLogLog使用

    PFADD命令

    PFADD命令,向指定的HyperLogLog添加指定的元素。

    基本语法:

    PFADD key element [element ...]
    
    • 1

    基本用法:

    127.0.0.1:6379> pfadd pfkey1 a b c d e f g h
    (integer) 1
    
    • 1
    • 2

    PFCOUNT命令

    返回HyperLogLog在键处观察到的集合的近似基数。

    基本语法:

    PFCOUNT key [key ...]
    
    • 1

    基本用法:

    127.0.0.1:6379> pfcount pfkey1
    (integer) 8
    
    # 我们多设置几个key
    127.0.0.1:6379> pfadd pfkey2 i j k
    (integer) 1
    # pfcount也可以计算多个key的总和
    127.0.0.1:6379> pfcount pfkey1 pfkey2
    (integer) 11
    
    # 计算总数时,会进行去重
    127.0.0.1:6379> pfadd pfkey3 j k l
    (integer) 1
    127.0.0.1:6379> pfcount pfkey1 pfkey2 pfkey3
    (integer) 12
    
    # 对单个key也会进行去重
    127.0.0.1:6379> pfadd pfkey4 a b a c
    (integer) 1
    127.0.0.1:6379> pfcount pfkey4
    (integer) 3
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    PFMERGE命令

    将N个不同的hyperlogglog合并为一个。

    基本语法:

    PFMERGE destkey sourcekey [sourcekey ...]
    
    • 1

    基本用法:

    # 合并并去重
    127.0.0.1:6379> pfmerge mergekey pfkey1 pfkey2 pfkey3 pfkey4
    OK
    127.0.0.1:6379> pfcount mergekey
    (integer) 12
    
    • 1
    • 2
    • 3
    • 4
    • 5

    注意!HyperLogLog统计并不是精确的

    HyperLogLog 的统计规则是基于概率完成的,所以它给出的统计结果是有一定误差的,标准误算率是 0.81%。这也就意味着,你使用 HyperLogLog 统计的 UV 是 100 万,但实际的 UV 可能是 101 万。虽然误差率不算大,但是,如果你需要精确统计结果的话,最好还是继续用 Set 或 Hash 类型。

  • 相关阅读:
    常用的gpt网站
    专访阿里云 RocketMQ 团队:现代微服务架构需要新的消息系统
    「运维有小邓」审核并分析文件和文件夹访问权限
    【MySQL入门指北】MySQL 彻底删除
    【C++ 初阶】运算符重载详解✌
    Java Web 7 JavaScript 7.4 JavaScript 常用对象
    基于Java+vue前后端分离失物招领信息交互平台设计实现(源码+lw+部署文档+讲解等)
    spring bean实例注入到map 集合中
    wireguard协议分析
    Spring Cloud Gateway网关两种负载均衡
  • 原文地址:https://blog.csdn.net/A_art_xiang/article/details/126767562