18.HyperLoglog基数统计
-
Redis 经常使用的数据类型有字符串、列表、散列、集合和有序集合,但这些类型并不能满足所有的应用场景,因此,Redis 的后续版本不断的扩增其他数据类型来增强 Redis 适用能力。在 Redis 2.8.9 版本中新增了 HyperLogLog 类型。
-
HyperLoglog 是 Redis 重要的数据类型之一,它非常适用于海量数据的计算、统计,其特点是占用空间小,计算速度快。
HyperLoglog 采用了一种基数估计算法,因此,最终得到的结果会存在一定范围的误差(标准误差为 0.81%)。每个 HyperLogLog key 只占用 12 KB 内存,所以理论上可以存储大约
2^64
个值(long类型),而 set(集合)则是元素越多占用的内存就越多,两者形成了鲜明的对比 。
HyperLoglog 使用起来较为方便,但是其内部原理较为复杂,会用即可。
若不允许出错,需使用set或者自定义的数据类型
-
**基数定义:**一个集合中不重复的元素个数就表示该集合的基数,比如集合 {1,2,3,4,5,1,2} ,它的基数集合为 {1,2,3,4,5} ,所以基数为 5。**基数非常大时,是可以接受误差的。**HyperLogLog 正是通过基数估计算法来统计输入元素的基数。
HyperLoglog 不会储存元素值本身,因此,它不能像 set 那样,可以返回具体的元素值。HyperLoglog 只记录元素的数量,并使用基数估计算法,快速地计算出集合的基数是多少。
-
场景应用:HyperLogLog 也有一些特定的使用场景,它最典型的应用场景就是统计网站用户月活量,或者网站页面的 UV(网站独立访客)数据等。
UV 与 PV(页面浏览量) 不同,UV 需要去重,同一个用户一天之内的多次访问只能计数一次。这就要求用户的每一次访问都要带上自身的用户 ID,无论是登陆用户还是未登陆用户都需要一个唯一 ID 来标识。
传统的方式,set保存用户的id,然后就可以统计set中的元素数量作为标准判断!如:uuid、分布式id
这个方式如果保存大量的用户id,就会比较麻烦!我们的目的是为了计数,而不是保存用户id;当一个网站拥有巨大的用户访问量时,我们可以使用 Redis 的 HyperLogLog 来统计网站的 UV (网站独立访客)数据,它提供的去重计数方案,虽说不精确,但 0.81% 的误差足以满足 UV 统计的需求。
-
常用命令:
命令 | 说明 |
---|---|
PFADD key element [element …] | 添加指定元素到 HyperLogLog key 中。 |
PFCOUNT key [key …] | 返回指定 HyperLogLog key 的基数估算值。 |
PFMERGE destkey sourcekey [sourcekey …] | 将多个 HyperLogLog key 合并为一个 key,重复的元素取一个,即取并集。 |
- HyperLogLog 提供了三个常用命令,分别是
PFADD
、PFCOUNT
和PFMERGE
。实例演示:
#向指定的key中添加用户
remote:0>pfadd website1 u1 u2 u3
"1"
#向指定的key中添加用户
remote:0>pfadd website2 u3 u4 u5
"1"
#统计基数值
remote:0>pfcount website1
"3"
#重复元素不能添加成功,其基数仍然为3
remote:0>pfadd website1 u1
"0"
remote:0>pfcount website1
"3"
#添加新元素值
remote:0>pfadd website1 u6
"1"
#基数值变为4
remote:0>pfcount website1
"4"
#两站点重复元素仅记录一次
remote:0>pfcount website1 website2
"6"
#将两个key值合并为一个
remote:0>pfmerge dest-website website1 website2
"OK"
#使用合并后key统计基数值,重复的算一个
remote:0>pfcount dest-website
"6"