Redis之HyperLogLog

原创
2019/10/16 15:48
阅读数 5

需求: 如果我们要统计网站页面的UV (每天一个用户的多次访问算一次)

  • 我们可以想到的是使用set来保存访问用户的ip,key = date + 任意关键字 ,values = 用户的ip
  • sadd "2019-10-16 ips" 192.168.1.1  依次类推更换后面的ip,因为set的value值是唯一的所以可以达到一天内用户的ip唯一
  • 带来的问题,使用字符串来储存每个 IPv4 地址最多需要耗费 15 字节
  • 下表给出了使用集合记录不同数量的独立 IP 时,需要耗费的内存数量:
    独立 IP 数量一天一个月一年
    一百万15 MB 450 MB 5.4 GB
    一千万150 MB 4.5 GB 54 GB
    一亿1.5 GB 45 GB 540 GB
    随着集合记录的 IP 越来越多,消耗的内存也会越来越多。
    另外如果要储存 IPv6 地址的话,需要的内存还会更多一些。所以在redis 2.8.9版本添加了HyperLogLog的结构

HyperLogLog介绍

  • HyperLogLog 可以接受多个元素作为输入,并给出输入元素的基数估算值:
  • 基数:集合中不同元素的数量。比如 {'apple', 'banana', 'cherry', 'banana', 'apple'} 的基数就是 3 。
  • 估算值:算法给出的基数并不是精确的,可能会比实际稍微多一些或者稍微少一些,但会控制在合理的范围之内
  • HyperLogLog 的优点是,即使输入元素的数量或者体积非常非常大,计算基数所需的空间总是固定的、并且是很小的
  • 在 Redis 里面,每个 HyperLogLog 键只需要花费 12 KB 内存,就可以计算接近 2^64 个不同元素的基数。这和计算基数时,元素越多耗费内存就越多的集合形成鲜明对比。但是,因为 HyperLogLog 只会根据输入元素来计算基数,而不会储存输入元素本身,所以HyperLogLog 不能像集合那样,返回输入的各个元素

常用命令

  • pfadd key element [element ...]   向values内添加一个或者多个元素
  • pfcount element [element...]    
  • pfmerge destkey sourcekey [sourcekey ...]

 

展开阅读全文
打赏
0
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部