pfadd

用法和sadd一样

pfcount

用法和scard一样

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

当数据大时看看不精确率

<?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个时出现误差

下面看误差几率

<?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也可以接受

误差率也不算高。然后我们把上面的脚本再跑一边,也就相当于将数据重复加入一边,查看输出,可以发现,pfcount 的结果没有任何改变,还是 997593,说明它确实具备去重功能

pfmerge

  • 用于将多个 pf 计数值累加在一起形成一个新的 pf 值
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 所使用的空间那真是可以使用千斤对比四两来形容了

Redis 对 HyperLogLog 的存储进行了优化,在计数比较小时,它的存储空间采用稀疏矩阵存储,空间占用很小,仅仅在计数慢慢变大,稀疏矩阵占用空间渐渐超过了阈值时才会一次性转变成稠密矩阵,才会占用 12k 的空间

HyperLogLog(不精确的去重计数方案)的更多相关文章

  1. Java使用极小的内存完成对超大数据的去重计数,用于实时计算中统计UV

    Java使用极小的内存完成对超大数据的去重计数,用于实时计算中统计UV – lxw的大数据田地 http://lxw1234.com/archives/2015/09/516.htm Java使用极小 ...

  2. MONGODB03 - 分组计数_分组去重计数(基于 spring-data-mongodb)

    前因 项目中有查询MongoDB单表统计相关功能,涉及到MongoDB数据聚合相关操作,其中在多字段分组去重计数相关操作API上资料较少,spring-data-mongodb相关的API介绍也不够直 ...

  3. redis应用--HyperLogLog

    如果你负责开发维护一个大型的网站,有一天老板找产品经理要网站每个网页每天的 UV 数据,然后让你来开发这个统计模块,你会如何实现? 如果统计 PV 那非常好办,给每个网页一个独立的 Redis 计数器 ...

  4. Redis HyperLogLog用法简介

    (1)HyperLogLog简介 在Redis 在 2.8.9 版本才添加了 HyperLogLog,HyperLogLog算法是用于基数统计的算法,每个 HyperLogLog 键只需要花费 12 ...

  5. redis之HyperLogLog

    HyperLogLog 提供不精确的去重计数方案,虽然不精确但是也不是非常不精确,标准误差是 0.81%. 使用方法 HyperLogLog 提供了两个指令 pfadd 和 pfcount,根据字面意 ...

  6. Redis实战篇(三)基于HyperLogLog实现UV统计功能

    如果现在要开发一个功能: 统计APP或网页的一个页面,每天有多少用户点击进入的次数.同一个用户的反复点击进入记为 1 次,也就是统计 UV 数据. 让你来开发这个统计模块,你会如何实现? 如果统计 P ...

  7. Redis其他数据结构

    用户日活月活怎么统计 - Redis HyperLogLog 详解 HyperLogLog 提出问题 我们先思考一个常见的业务问题:如果你负责开发维护一个大型的网站,有一天老板找产品经理要网站每个网页 ...

  8. 如何用redis统计海量UV?

    前言 我们先思考一个常见的业务问题:如果你负责开发维护一个大型的网站,有一天老板找产品经理要网站每个网页每天的 UV 数据,然后让你来开发这个统计模块,你会如何实现? 统计uv的常用方法以及优缺点 其 ...

  9. Redis数据类型:五大基本数据类型及三种特殊类型

    String (字符串类型) String是redis最基本的类型,你可以理解成Memcached一模一样的类型,一个key对应一个value. String类型是二进制安全的,意思是redis的st ...

随机推荐

  1. linux内核启动时报错ubi0 error: validate_ec_hdr: bad VID header offset 256, expected 64

    1.详细错误报告如下: ubi0 error: validate_ec_hdr: bad VID header offset 256, expected 64 ubi0 error: validate ...

  2. Mininet实验 设置带宽之简单性能测试

    原文:设置带宽之简单性能测试 这个实验主要还是说明通过python程序来设定Mininet中的链路带宽. 目的: Python脚本实现自定义拓扑 设置链路的带宽.延迟及丢包率 iperf测试主机间的带 ...

  3. python文件操作的坑( FileNotFoundError: [Errno 2] No such file or directory...)

    环境:Windows8.1, Python3.6  pycharm community 2017   c盘下有一个配置文件:setup   with open('c:\\setup','r') as ...

  4. pairs 和 ipairs异同

    同:都是能遍历集合(表.数组) 异:ipairs 仅仅遍历值,按照索引升序遍历,索引中断停止遍历.即不能返回 nil,只能返回数字 0,如果遇到 nil 则退出.它只能遍历到集合中出现的第一个不是整数 ...

  5. QWebEngineView_简单例子_01

    工程名 : WebEngine01 1.WebEngine01.pro #------------------------------------------------- # # Project c ...

  6. FreeSouth的学习osg小贴士

    http://www.osgchina.org/index.php?option=com_content&view=article&id=150&catid=91&It ...

  7. 前端引用公共html模块方案

    最近临时一个负责公司官网的妹纸请假,于是临时接手了下官网的项目,官网都是静态页面,算是很简单的,但发现页面挺多,而每个页面总有部分是和其他页面一模一样的,比如页头.页尾等,这样就导致一个地方的修改要在 ...

  8. [转载]SQL语句练习

    .查询“生物”课程比“物理”课程成绩高的所有学生的学号: 思路: 获取所有有生物课程的人(学号,成绩) - 临时表 获取所有有物理课程的人(学号,成绩) - 临时表 根据[学号]连接两个临时表: 学号 ...

  9. SQL向一个表中批量插入&&删除大量数据

    插入: 1. 数据从另一个表中获取 (1)两表结构不一样insert into tb1 需要的列名 select 按照前面写上需要的列名 from tb2(2)两表结构一样insert into tb ...

  10. 基于js-spark-md5前端js类库,快速获取文件Md5值

    js-spark-md5是歪果仁开发的东西,有点多,但是我们只要一个js文件即可,具体类包我存在自己的oschina上,下载地址:https://git.oschina.net/jianqingwan ...