目录
特点
1、HyperLogLog是一种算法,并非redis独有。
2、在输入元素的数量或者体积非常非常大时,计算基数所需的空间总是固定的、并且是很小的。在 Redis 里面,每个 HyperLogLog 键只需要花费 12 KB 内存。这和计算基数时,元素越多耗费内存就越多的集合形成鲜明对比。
3、HyperLogLog 只会根据输入元素来计算基数,而不会储存输入元素本身,所以 HyperLogLog 不能像集合那样,返回输入的各个元素。
4、核心是基数估算算法,最终数值存在一定误差。基数估计的结果是一个带有 0.81% 标准错误(standard error)的近似值。
5、存储时并不会直接占用12k空间,它的存储空间采用稀疏矩阵存储,空间占用很小,仅仅在计数慢慢变大,稀疏矩阵占用空间渐渐超过了阈值时才会一次性转变成稠密矩阵,才会占用 12k 的空间。
在不追求绝对准确的情况下,使用概率算法算是一个不错的解决方案。概率算法不直接存储数据集合本身,通过一定的概率统计方法预估基数值,这种方法可以大大节省内存,同时保证误差控制在一定范围内。
操作
Redis 为 HyperLogLog提供了三个命令:
pfadd添加
pfadd key element [element ...]
pfadd一个已存在的元素时,元素估计数量不发生变化。比如我上边添加过xiaoming,再添加小明时,class:4的key内部存储不发生变化。
pfcount计算
pfcount key [key ...]
当它作用于多个key时,返回所有给定 HyperLogLog 的并集的近似基数,这个近似基数是通过将所有给定 HyperLogLog 合并至一个临时 HyperLogLog 来计算得出的。
pfmerge合并
pfmerge destkey sourcekey [sourcekey ...]
合并后的 HyperLogLog 的基数接近于所有输入 HyperLogLog 的可见集合(observed set)的并集。
然后计算可得
应用场景
统计uv案例
把每天访问的ip放入HyperLogLog结构中
如果统计某天uv,直接使用pfcount 日期即可
如果统计某几天uv,先合并,在计算即可
统计日活、月活案例
略
小结
了解熟悉HyperLogLog,对它有一个基本认知