redis | 十、redis之HyperLogLog

78 阅读3分钟

redis系列文章:
liudongdong.top/categories/…
本篇来源:
liudongdong.top/archives/re…
公众号:雨中散步撒哈拉
备注:欢迎关注公众号,一起学习,共同进步!

一、HyperLogLog基数统计

HyperLogLog,下面简称为HLL,它是 LogLog 算法的升级版,作用是能够提供不精确的去重计数。存在以下的特点:

  1. 代码实现较难。

  2. 能够使用极少的内存来统计巨量的数据,在 Redis 中实现的 HyperLogLog,只需要12K内存就能统计2^64个数据。

  3. 计数存在一定的误差,误差率整体较低。标准误差为 0.81% 。

  4. 误差可以被设置辅助计算因子进行降低。

稍微对编程中的基础数据类型内存占用有了解的同学,应该会对其只需要12K内存就能统计2^64个数据而感到惊讶。为什么这样说呢,下面我们举下例子:

取 Java 语言来说,一般long占用8字节,而一字节有8位,即:1 byte = 8 bit,即long数据类型最大可以表示的数是:2^63-1。对应上面的2^64个数,假设此时有2^63-1这么多个数,从 0 ~ 2^63-1,按照long以及1k = 1024字节的规则来计算内存总数,就是:((2^63-1) * 8/1024)K,这是很庞大的一个数,存储空间远远超过12K。而 HyperLogLog 却可以用 12K 就能统计完。

1. pfadd元素添加

将除了第一个参数以外的参数存储到以第一个参数为变量名的HyperLogLog结构中.

这个命令的一个副作用是它可能会更改这个HyperLogLog的内部来反映在每添加一个唯一的对象时估计的基数(集合的基数).

如果一个HyperLogLog的估计的近似基数在执行命令过程中发了变化, PFADD 返回1,否则返回0,如果指定的key不存在,这个命令会自动创建一个空的HyperLogLog结构(指定长度和编码的字符串).

如果在调用该命令时仅提供变量名而不指定元素也是可以的,如果这个变量名存在,则不会有任何操作,如果不存在,则会创建一个数据结构(返回1).

了解更多HyperLogLog数据结构,请查阅PFCOUNT命令页面.

返回值
integer-reply

如果 HyperLogLog 的内部被修改了,那么返回 1,否则返回 0 .

实例

127.0.0.1:6379> pfadd hll one two three four
(integer) 1
127.0.0.1:6379> pfadd hll five sex
(integer) 1
127.0.0.1:6379>

2. pfcount元素统计(不重复统计)

Hyperloglog 是用来做基数统计的数据类型

假设有如下一个数据集 { 1, 3, 5, 7, 9, 5 },那么这个数据集的基数就是 { 1, 3, 7, 9},基数即是值一个数据集中的不重复元素

返回值
integer-reply:

PFADD添加的唯一元素的近似数量.

实例

127.0.0.1:6379> pfcount hll
(integer) 6

3. PFMERGE元素合并

PFMERGE destkey sourcekey [sourcekey ...]
将多个 HyperLogLog 合并(merge)为一个 HyperLogLog , 合并后的 HyperLogLog 的基数接近于所有输入 HyperLogLog 的可见集合(observed set)的并集.

合并得出的 HyperLogLog 会被储存在目标变量(第一个参数)里面, 如果该键并不存在, 那么命令在执行之前, 会先为该键创建一个空的.

返回值
simple-string-reply: 这个命令只会返回 OK.

127.0.0.1:6379> pfadd hll2 1 2 3 4
(integer) 1
127.0.0.1:6379> pfmerge hll3 hll hll2
OK
127.0.0.1:6379> pfcount hll3
(integer) 10
127.0.0.1:6379>