• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
Y-wee
博客园    首页    新随笔    联系   管理     

redis中hyperloglog基数统计

redis中hyperloglog基数统计

在工作当中,我们经常会遇到与统计相关的功能需求,比如统计网站PV(PageView页面访问量),可以使用Redis的incr、incrby轻松实现;但像UV(UniqueVisitor,独立访客)、独立IP数、搜索记录数等需要去重和计数的问题如何解决?这种求集合中不重复元素个数的问题称为基数问题

解决基数问题有很多种方案

  • 数据存储在MySQL表中,使用distinct count计算不重复个数
  • 使用Redis提供的hash、set、bitmaps等数据结构来处理

以上的方案结果精确,但随着数据不断增加,导致占用空间越来越大,对于非常大的数据集是不切实际的

能否能够降低一定的精度来平衡存储空间?Redis推出了HyperLogLog, 2.8.9 版本添加了 HyperLogLog 结构

Redis HyperLogLog 是用来做基数统计的算法,HyperLogLog 的优点是,在输入元素的数量或者体积非常非常大时,计算基数所需的空间总是固定的、并且是很小的;在 Redis 里面,每个 HyperLogLog 键只需要花费 12 KB 内存,就可以计算接近 2^64 个不同元素的基 数。这和计算基数时,元素越多耗费内存就越多的集合形成鲜明对比

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

什么是基数:比如数据集 {1, 3, 5, 7, 5, 7, 8}, 那么这个数据集的基数集为 {1, 3, 5 ,7, 8}, 基数(不重复元素)为5。 基数估计就是在误差可接受的范围内,快速计算基数

应用场景

说明:

  • 基数不大,数据量不大就用不上,会有点大材小用浪费空间
  • 有局限性,就是只能统计基数数量,而没办法去知道具体的内容是什么
  • 0.81%错误率,会有误差

一般使用:

  • 统计注册 IP 数
  • 统计每日访问 IP 数
  • 统计页面实时 UV 数
  • 统计在线用户数
  • 统计用户每天搜索不同词条的个数

传统的方式:

set保存用户的id,然后就可以统计set中的元素数量作为判断的标准,这个方式如果保存大量的用户id,就会比较麻烦,而且浪费内存!我们的目的是为了计数,而不是保存用户id

基本使用

  • 添加指定元素到 HyperLogLog 中:pfadd key element1 element2 element3......,eg:
127.0.0.1:6379> pfadd key1 e1 e2 e3 e4 e5 e6 e7
(integer) 1

将所有元素添加到指定HyperLogLog数据结构中,如果执行命令后HLL估计的近似基数发生变化,则返回1,否则返回0

  • 查询key对应的 HyperLogLog 中的元素数量:pfcount key,eg:
127.0.0.1:6379> pfcount key1
(integer) 7
  • 将一个或多个 key 对应的 HyperLogLog 合并到指定key(比如每月活跃用户可以使用每天的活跃用户来合并计算可得):pfmerge key key key......(第一个key是目标,后面的key是源),eg:
127.0.0.1:6379> pfcount key1
(integer) 7
127.0.0.1:6379> pfadd key2 k2e1 k2e2 k2e3
(integer) 1
127.0.0.1:6379> pfmerge key3 key1 key2
OK
127.0.0.1:6379> pfcount key3
(integer) 10
记得快乐
posted @ 2021-03-20 14:56  Y-wee  阅读(88)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3