Redis hyperloglog去重复统计

就比如一个大型的网站会少不了大量的用户访问,就比如天猫的uv访问统计,一个用户一天内访问多次顶多算一次uv;淘宝、天猫首页的uv平均每天是1~1.5亿左右;,每天存1.5亿个用户的ip,访问者来了先去查是否存在,不存在则写入,那么这个存储得占多大空间?另外统计的读取速度又能保证达到预期吗?

这里可能想到的是哈希,redis 的hset;

比如

//今天ip192.168.1.1用户访问1次
127.0.0.1:6379> hset today1 192.168.1.1 1
(integer) 1
127.0.0.1:6379> hset today1 192.168.1.2 1
(integer) 1
127.0.0.1:6379> hset today1 192.168.1.3 1
(integer) 1
127.0.0.1:6379> hset today1 192.168.1.5 1
(integer) 1
127.0.0.1:6379> hgetall today1
1) "192.168.1.1"
2) "1"
3) "192.168.1.2"
4) "1"
5) "192.168.1.3"
6) "1"
7) "192.168.1.5"
8) "1"
127.0.0.1:6379>

hash 命令 keyday,ip,1次

按照ipv4的结构来说明,每个ipv4的地址最多是15个字节(ip=”192.168.1.1“,最多xxx.xxx.xxx.xxx),某一天的1.5亿*15个字节=2G,一个月60G,redis还咋玩。

这里hyperloglog就用上了!

 

 

Redis 在 2.8.9 版本添加了 HyperLogLog 结构。
Redis HyperLogLog 是用来做基数统计的算法,HyperLogLog 的优点是,在输入元素的数量或者体积非常非常大时,计算基数所需的空间总是固定 的、并且是很小的。
在 Redis 里面,每个 HyperLogLog 键只需要花费 12 KB 内存,就可以计算接近 2^64 个不同元素的基 数。这和计算基数时,元素越多耗费内存就越多的集合形成鲜明对比。
但是,因为 HyperLogLog 只会根据输入元素来计算基数,而不会储存输入元素本身,所以 HyperLogLog 不能像集合那样,返回输入的各个元素。

 

 为什么是12Kb?

每个桶取6位,16384*6➗8=12kb,每个桶有6位,最大全部都是1,值就是63。

通过牺牲准确率来换取空间,误差仅仅是0.81%左右(来自官方说明),对于不要求绝对精准率下的场景可以使用,因为概率算法不直接存储数据本身,通过一定的概率统计方法预估基数值,同时保证误差在一定范围内,由于又不存储数据故此可以大大节约内存。

操作

127.0.0.1:6379> PFADD taobao:uv 111 112 113
(integer) 1
127.0.0.1:6379> PFCOUNT taobao:uv
(integer) 3
127.0.0.1:6379> PFADD taobao:uv 111 112 113 114 115
(integer) 1
127.0.0.1:6379> PFADD taobao:uv 111 112 113 114 115
(integer) 0
127.0.0.1:6379> PFADD taobao:uv 116
(integer) 1
127.0.0.1:6379> del taobao:uv
(integer) 1
127.0.0.1:6379>

 

127.0.0.1:6379> PFADD jd:uv1 1 2 3
(integer) 1
127.0.0.1:6379> PFADD jd:uv2 1 2 3 4 5
(integer) 1
127.0.0.1:6379> PFADD jd:uv1 2
(integer) 0
127.0.0.1:6379> PFCOUNT jd:uv1
(integer) 3
127.0.0.1:6379> PFMERGE result jd:uv1 jd:uv2
OK
127.0.0.1:6379> PFCOUNT result
(integer) 5
127.0.0.1:6379>

应用场景

说明:

  1. 基数不大,数据量不大就用不上,会有点大材小用浪费空间
  2. 有局限性,就是只能统计基数数量,而没办法去知道具体的内容是什么
  3. 和bitmap相比,属于两种特定统计情况,简单来说,HyperLogLog 去重比 bitmap 方便很多
  4. 一般可以bitmap和hyperloglog配合使用,bitmap标识哪些用户活跃,hyperloglog计数

一般使用:

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

 

posted @ 2018-09-30 23:08  温柔的风  阅读(170)  评论(0编辑  收藏  举报