redis中的HyperLogLog
redis中的HyperLogLog
HyperLogLog是一个专门为了计算集合的基数而创建的概率算法,对于一个给定的集合,HyperLogLog可以计算出这个集合的近似基数。
近似基数并非集合的实际基数,它可能会比实际的基数小一点或者大一点,但误差会在一个合理的范围内。因此那些不需要知道实际基数或者因为条件限制而无法计算出实际基数的程序就可以把这个近似基数当作集合的基数来使用。
HyperLogLog的优点在于它计算近似基数所需的内存并不会因为集合的大小而改变,无论集合包含的元素有多少个,HyperLogLog进行计算所需的内存总是固定的,并且是非常少的。具体到实现上,Redis的每个HyperLogLog只需要使用12KB内存空间,就可以对接近:2^64 个元素进行计数,而算法的标准误差仅为0.81%,因此它计算出的近似基数是相当可信的。
redis中的相关命令
1. FPADD:对集合元素进行计数
用户可以执行PFADD命令,使用HyperLogLog对给定的一个或者多个集合元素进行计数
PFADD hyperloglog element [element ...]
- 如果给定的元素都已经进行过计数,该命令将返回0,表示HyperLogLog计算出的近似基数没有发生变化。
- 与此相反,如果给定元素中出现了至少一个之前没有进行过的计数的元素,导致HyperLogLog计算出的近似基数发生了变化,那么该命令将会返回1.
其他信息
- 复杂度:O(N),其中N为用户给定的元素数量。
- 版本要求:PFADD命令从Redis 2.8.9版本开始可用。
PFCOUNT:返回集合的近似基数
在使用PFADD命令对元素进行计数之后,用户可以通过执行PFCOUNT命令来获取HyperLogLog为集合计算出的近似基数,当给定的HyperLogLog不存在时,该命令就会返回0作为结果:
PFCOUND hyperloglog [hyperloglog ...]
当用户向该命令传入多个HyperLogLog时,该命令将对所有给定的HyperLogLog执行并集计算,然后返回并集HyperLogLog计算出来的近似基数。
其他信息
- 复杂度:O(N),其中N为用户给定的HyperLogLog数量。
- 版本要求:PFCOUNT命令从Redis 2.8.9版本开始可用。
- hyperloglog可以作为一个内存开销低的唯一计数器,应为HyperLogLog不会随着基数信息的增多而变大。或者用于检测重复信息,因为Hyperloglog使用的是概率算法,所以即使信息的长度非常长,HyperLogLog判断信息是否重复的时间也非常短。
PFMERGE:计算多个HyperLogLog的并集
PFMERGE命令可以对多个给定的HyperLogLog执行并集计算,并把计算得出的并集HyperLogLog保存到指定的键中。
PFMERGE destination hyperloglog [hyperloglog ...]
这里需要知道PFCOUNT命令在计算多个HyperLogLog的近似基数时会执行以下操作:
- 在内部调用PFMERGE命令,计算所有给定的HyperLogLog的并集,并将这个并集存储到一个临时的HyperLogLog中。
- 对临时HyperLogLog执行PFCOUNT命令,得到它的近似基数。
- 删除临时HyperLogLog。
- 向用户返回之前得到的近似基数。
其他信息
- 复杂度:O(N),其中N为用户给定的HyperLogLog数量。
- 版本要求:PFMERGE命令从Redis 2.8.9版本开始可用。
总结
- HyperLogLog是一种算法,但不是存储数据的容器。
- HyperLogLog可以对大量元素进行计数,并计算出来这些元素的近似基数
- 无论被计数的元素有多少个,HyperLogLog之使用固定大小的内存,其内存占用不会因为被计数元素的增多而增多。
- HyperLogLog不仅可以用于计数问题,还可以用于去重问题。