Redis应用 — HyperLogLog

Redis应用 — HyperLogLog

何为 HyperLogLog

HyperLogLog 是一种高级数据结构,在数据去重统计时非常有用。假设我们需要对网站的每个页面计算 UV,每个用户一天之内的多次访问只计算一次,这里涉及到数据的去重。

回顾以前的知识点,可以利用 set 数据结构数据无重复的特性来实现。以 网页ID + 今天日期 为 key,用户ID 为 value,用户每次访问页面就 sadd 一个用户ID进去。统计时使用 scard 取出集合的大小,这个数据就是页面的 UV 数。

set结构统计页面UV

但是如果访问量过于巨大,所需要的 set 集合空间将会非常巨大,非常浪费空间。并且这个 UV 数没必要特别精确,有没有其他好的办法?HyperLogLog 就是用来解决这种统计问题的,其提供不精确的统计方案,标准误差为 0.81%。

基本使用

  • pfadd key element [element …]:添加一个元素
  • pfcount key [key …]:计算总数
  • pfmerge destkey sourcekey [sourcekey …]:合并两个 key

【pfadd / pfcount】
pfadd 指令和 set 的 sadd 一样,设置一个值。pfcount 和 set 的 scard 一样,用于统计集合元素的总数。

1
2
3
4
5
6
7
8
9
10
11
12
13
# docker 镜像:redislabs/rebloom
127.0.0.1:6379> pfadd codehole user1
(integer) 1
127.0.0.1:6379> pfcount codehole
(integer) 1
127.0.0.1:6379> pfadd codehole user2
(integer) 1
127.0.0.1:6379> pfcount codehole
(integer) 2
127.0.0.1:6379> pfadd codehole user3 user4 user5 user6
(integer) 1
127.0.0.1:6379> pfcount codehole
(integer) 6

【pfmerge】
如果需要将两个页面的数据进行合并,其 UV 也需要重新统计,pfmerge 指令可以用来将多个 key 合并。

1
2
3
4
5
6
7
8
9
10
127.0.0.1:6379> pfadd key v1
(integer) 1
127.0.0.1:6379> pfadd key v2
(integer) 1
127.0.0.1:6379> pfcount key
(integer) 2
127.0.0.1:6379> pfmerge codehole key # 把 key 合并到 codehole
OK
127.0.0.1:6379> pfcount codehole
(integer) 8

Comments