数据结构之HyperLogLog
HyperLogLog是一个专门为了计算集合的基数而创建的概率算法,对于一个给定的集合,HyperLogLog可以计算出这个集合的近似基数:近似基数并非集合的实际基数,它可能会比实际的基数小一点或者大一点,但是估算基数和实际基数之间的误差会处于一个合理的范围之内,因此那些不需要知道实际基数或者因为条件限制而无法计算出实际基数的程序就可以把这个近似基数当作集合的基数来使用。
HyperLogLog的优点在于它计算近似基数所需的内存并不会因为集合的大小而改变,无论集合包含的元素有多少个,HyperLogLog进行计算所需的内存总是固定的,并且是非常少的。
PFADD:对集合元素进行计数
PFADD hyperloglog element [element ...]
如果给定的元素中出现了至少一个之前没有进行过计数的元素,导致HyperLogLog计算出的近似基数发生了变化,那么PFADD命令将返回1。
PFCOUNT:返回集合的近似基数
在使用PFADD命令对元素进行计数之后,用户可以通过执行PFCOUNT命令来获取HyperLogLog为集合计算出的近似基数。
当用户向PFCOUNT传入多个HyperLogLog时,PFCOUNT命令将对所有给定的Hyper-LogLog执行并集计算,然后返回并集HyperLogLog计算出的近似基数。
PFMERGE:计算多个HyperLogLog的并集
PFMERGE命令可以对多个给定的HyperLogLog执行并集计算,然后把计算得出的并集HyperLogLog保存到指定的键中。
redis> PFADD numbers1 128 256 512
(integer) 1redis> PFADD numbers2 128 256 512
(integer) 1redis> PFADD numbers3 128 512 1024
(integer) 1
redis> PFMERGE union-numbers numbers1 numbers2 numbers3
OKredis> PFCOUNT union-numbers
(integer) 4
PFCOUNT命令在计算多个HyperLogLog的近似基数时会执行以下操作:
1)在内部调用PFMERGE命令,计算所有给定HyperLogLog的并集,并将这个并集存储到一个临时的HyperLogLog中。
2)对临时HyperLogLog执行PFCOUNT命令,得到它的近似基数(因为这是针对单个HyperLogLog的PFCOUNT,所以这个操作不会引起循环调用)。
3)删除临时HyperLogLog。
4)向用户返回之前得到的近似基数。
当程序需要对多个HyperLogLog调用PFCOUNT命令,并且这个调用可能会重复执行多次时,我们可以考虑把这一调用替换成相应的PFMERGE命令调用。
HyperLogLog不仅可以用于计数问题,还可以用于去重问题。