pfaddphp
用法和sadd同样
java
pfcountpython
127.0.0.1:6379> get lan (nil) 127.0.0.1:6379> pfadd lan js (integer) 1 127.0.0.1:6379> pfadd lan php (integer) 1 127.0.0.1:6379> pfcount lan (integer) 2 127.0.0.1:6379> pfadd lan php (integer) 0 127.0.0.1:6379> pfcount lan (integer) 2 127.0.0.1:6379> pfadd lan java python lua (integer) 1 127.0.0.1:6379> pfcount lan (integer) 5
当数据大时看看不精确率redis
<?php $num=$argv[1]??200; echo $num.PHP_EOL; $redis=new redis(); $redis->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 500 500 1-----i=128----pfcount=129
第128个时出现偏差centos
下面看偏差概率优化
<?php $num=$argv[1]??200; echo $num.PHP_EOL; $redis=new redis(); $redis->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 500 500 i=500----pfcount=500---->0----0 [root@centos1 php]# php redis_hyperloglog.php 1000 1000 i=1000----pfcount=999---->-1-----0.001 [root@centos1 php]# php redis_hyperloglog.php 5000 5000 i=5000----pfcount=4996---->-4-----0.0008 [root@centos1 php]# php redis_hyperloglog.php 50000 50000 i=50000----pfcount=50115---->115----0.0023 [root@centos1 php]# php redis_hyperloglog.php 10000 10000 i=10000----pfcount=10009---->9----0.0009 [root@centos1 php]# php redis_hyperloglog.php 100000 100000 i=100000----pfcount=99839---->-161-----0.00161 [root@centos1 php]# php redis_hyperloglog.php 1000000 1000000 i=1000000----pfcount=997593---->-2407-----0.002407
100w偏差率在0.002407也能够接受lua
偏差率也不算高。而后咱们把上面的脚本再跑一边,也就至关于将数据重复加入一边,查看输出,能够发现,pfcount 的结果没有任何改变,仍是 997593,说明它确实具有去重功能code
pfmergeget
127.0.0.1:6379> pfadd boy Tom John (integer) 1 127.0.0.1:6379> pfadd girl Lily lucy Andy (integer) 1 127.0.0.1:6379> pfmerge student boy girl OK 127.0.0.1:6379> pfcount student (integer) 5
HyperLogLog 它须要占据必定 12k 的存储空间,因此它不适合统计单个用户相关的数据。若是你的用户上亿,能够算算,这个空间成本是很是惊人的。可是相比 set 存储方案,HyperLogLog 所使用的空间那真是可使用千斤对比四两来形容了perl
Redis 对 HyperLogLog 的存储进行了优化,在计数比较小时,它的存储空间采用稀疏矩阵存储,空间占用很小,仅仅在计数慢慢变大,稀疏矩阵占用空间渐渐超过了阈值时才会一次性转变成稠密矩阵,才会占用 12k 的空间