redis系列文章: https://liudongdong.top/categories/redis 本篇来源: https://liudongdong.top/archives/redisshi-redis-zhi-hyperloglog 公众号:雨中散步撒哈拉 备注:欢迎关注公众号,一起学习,共同进步!
一、HyperLogLog基数统计
HyperLogLog,下面简称为HLL,它是 LogLog 算法的升级版,作用是能够提供不精确的去重计数。存在以下的特点:
- 代码实现较难。
- 能够使用极少的内存来统计巨量的数据,在 Redis 中实现的 HyperLogLog,只需要12K内存就能统计2^64个数据。
- 计数存在一定的误差,误差率整体较低。标准误差为 0.81% 。
- 误差可以被设置辅助计算因子进行降低。
稍微对编程中的基础数据类型内存占用有了解的同学,应该会对其只需要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 .
实例
代码语言:javascript复制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添加的唯一元素的近似数量.
实例
代码语言:javascript复制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.
代码语言:javascript复制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>