HyperLogLog
介绍
Redis HyperLogLog 是Redis 2.8.9版本新增的数据类型,是一种用于[统计基数]的数据集和类型,基数统计是指统计一个集合中不重复的元素个数。但要注意,HyperLogLog是统计规则是基于概率完成的,不是非常准确,标准误算率是0.81%。
所以,简单来说HyperLogLog提供不精确的去重计数.
HyperLogLog的优点是,在输入元素的数量或体积非常非常大是,计算基数所需的内存空间总量是固定的、并且是很小的。
在Redis里,每个HyperLogLog键只需要花费12KB内存,就可以计算接近2^64
个不同元素的基数,和元素越多就约耗费内存的Set和Hash类型相比,HyperLogLog就非常节省空间。
这什么概念?举个例子给大家对比一下。
用Java语言来说,一般long类型占用8字节,而1字节有8位,即:1byte = 8bit,即long数据类型最大可以表示的数是:2^63-1
。对应上面的2^64
个数,假设此时有2^63-1
这么多个数,从0 ~ 2^63-1
,按照long
以及1k=1024
字节的规程来计算内存总数,就是:((2^64-1) * 8/1024)k
,这是很庞大的一个数,存储空间远远超过12K
,而HyperLoglog
却可以用12k
就能统计完。
内部实现
HyperLogLog的实现涉及到很多数学问题,太费脑子了,如果你想了解以下可以看看这个: HyperLogLog
常见命令
HyperLogLog 命令就3个:
# 添加指定元素到 HyperLogLog中
PFADD key element [element ...]
# 返回给定 HyperLogLog的基数估算值.
PFCOUNT key [key ...]
# 将多个 HyperLogLog 合并为一个 HyperLogLog
PFMERGE destkey sourcekey [sourcekey ...]
应用场景
百万级网页UV计数
Redis HyperLogLog 优势在于只需要花费12KB内存,就可以计算接近2^64个元素的基数,和元素越多越耗费内存的Set和Hash类型相比,HyperLogLog就非常节省空间。
所以,非常适合统计百万级以上的网页UV场景。
在统计UV时,你可以用PFADD命令(用于向HyperLogLog中添加新元素)把访问页面的每个用户都添加到HyperLogLog中。
PFADD page1:uv user1 user2 user3 user4 user5
接下来,就可以用PFCOUNT命令直接获得page1的UV值1了,这个命令的作用就是返回HyperLogLog的统计结果。
PFCOUNT page1:uv
不过,有一点需要注意一下,HyperLogLog的统计规则是基于概率完成的,所以他给出的统计结果是有一定误差的,标准的误差结果是0.81%
这也就意味着,你使用HyperLogLog统计的UV是100万,但实际的UV可能是101万。虽然误差率不算大,但是,如果你需要精确统计结果的话,最好还是继续使用Set和Hash类型。