pfadd
用法和sadd一样
pfcount
用法和scard一样127.0.0.1:6379> get lan(nil)127.0.0.1:6379> pfadd lan js(integer) 1127.0.0.1:6379> pfadd lan php(integer) 1127.0.0.1:6379> pfcount lan(integer) 2127.0.0.1:6379> pfadd lan php(integer) 0127.0.0.1:6379> pfcount lan(integer) 2127.0.0.1:6379> pfadd lan java python lua(integer) 1127.0.0.1:6379> pfcount lan(integer) 5
当数据大时看看不精确率
connect('127.0.0.1',6379);$redis->del('users');for($i=1;$i<=$num;$i++){ $r=$redis->pfadd('users',['user_'.$i]); $total=$redis->pfcount('users'); if($total!=$i){ echo $r.'-----i='.$i."----pfcount=".$total.PHP_EOL; break; }}
[root@centos1 php]# php redis_hyperloglog.php 5005001-----i=128----pfcount=129
第128个时出现误差
下面看误差几率
connect('127.0.0.1',6379);$redis->del('users');for($i=1;$i<=$num;$i++){ $r=$redis->pfadd('users',['user_'.$i]); $total=$redis->pfcount('users'); if($i == $num){ echo 'i='.$i."----pfcount=".$total.'---->'.($total-$i).'----'.($total-$i)/$i.PHP_EOL; }}
[root@centos1 php]# php redis_hyperloglog.php 500500i=500----pfcount=500---->0----0[root@centos1 php]# php redis_hyperloglog.php 10001000i=1000----pfcount=999---->-1-----0.001[root@centos1 php]# php redis_hyperloglog.php 50005000i=5000----pfcount=4996---->-4-----0.0008[root@centos1 php]# php redis_hyperloglog.php 5000050000i=50000----pfcount=50115---->115----0.0023[root@centos1 php]# php redis_hyperloglog.php 1000010000i=10000----pfcount=10009---->9----0.0009[root@centos1 php]# php redis_hyperloglog.php 100000100000i=100000----pfcount=99839---->-161-----0.00161[root@centos1 php]# php redis_hyperloglog.php 10000001000000i=1000000----pfcount=997593---->-2407-----0.002407
100w误差率在0.002407也可以接受
误差率也不算高。然后我们把上面的脚本再跑一边,也就相当于将数据重复加入一边,查看输出,可以发现,pfcount 的结果没有任何改变,还是 997593,说明它确实具备去重功能
pfmerge
- 用于将多个 pf 计数值累加在一起形成一个新的 pf 值
127.0.0.1:6379> pfadd boy Tom John(integer) 1127.0.0.1:6379> pfadd girl Lily lucy Andy(integer) 1127.0.0.1:6379> pfmerge student boy girlOK127.0.0.1:6379> pfcount student(integer) 5
HyperLogLog 它需要占据一定 12k 的存储空间,所以它不适合统计单个用户相关的数据。如果你的用户上亿,可以算算,这个空间成本是非常惊人的。但是相比 set 存储方案,HyperLogLog 所使用的空间那真是可以使用千斤对比四两来形容了
Redis 对 HyperLogLog 的存储进行了优化,在计数比较小时,它的存储空间采用稀疏矩阵存储,空间占用很小,仅仅在计数慢慢变大,稀疏矩阵占用空间渐渐超过了阈值时才会一次性转变成稠密矩阵,才会占用 12k 的空间