HyperLogLog(不精确的去重计数方案)
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(不精确的去重计数方案)的更多相关文章
- Java使用极小的内存完成对超大数据的去重计数,用于实时计算中统计UV
Java使用极小的内存完成对超大数据的去重计数,用于实时计算中统计UV – lxw的大数据田地 http://lxw1234.com/archives/2015/09/516.htm Java使用极小 ...
- MONGODB03 - 分组计数_分组去重计数(基于 spring-data-mongodb)
前因 项目中有查询MongoDB单表统计相关功能,涉及到MongoDB数据聚合相关操作,其中在多字段分组去重计数相关操作API上资料较少,spring-data-mongodb相关的API介绍也不够直 ...
- redis应用--HyperLogLog
如果你负责开发维护一个大型的网站,有一天老板找产品经理要网站每个网页每天的 UV 数据,然后让你来开发这个统计模块,你会如何实现? 如果统计 PV 那非常好办,给每个网页一个独立的 Redis 计数器 ...
- Redis HyperLogLog用法简介
(1)HyperLogLog简介 在Redis 在 2.8.9 版本才添加了 HyperLogLog,HyperLogLog算法是用于基数统计的算法,每个 HyperLogLog 键只需要花费 12 ...
- redis之HyperLogLog
HyperLogLog 提供不精确的去重计数方案,虽然不精确但是也不是非常不精确,标准误差是 0.81%. 使用方法 HyperLogLog 提供了两个指令 pfadd 和 pfcount,根据字面意 ...
- Redis实战篇(三)基于HyperLogLog实现UV统计功能
如果现在要开发一个功能: 统计APP或网页的一个页面,每天有多少用户点击进入的次数.同一个用户的反复点击进入记为 1 次,也就是统计 UV 数据. 让你来开发这个统计模块,你会如何实现? 如果统计 P ...
- Redis其他数据结构
用户日活月活怎么统计 - Redis HyperLogLog 详解 HyperLogLog 提出问题 我们先思考一个常见的业务问题:如果你负责开发维护一个大型的网站,有一天老板找产品经理要网站每个网页 ...
- 如何用redis统计海量UV?
前言 我们先思考一个常见的业务问题:如果你负责开发维护一个大型的网站,有一天老板找产品经理要网站每个网页每天的 UV 数据,然后让你来开发这个统计模块,你会如何实现? 统计uv的常用方法以及优缺点 其 ...
- Redis数据类型:五大基本数据类型及三种特殊类型
String (字符串类型) String是redis最基本的类型,你可以理解成Memcached一模一样的类型,一个key对应一个value. String类型是二进制安全的,意思是redis的st ...
随机推荐
- linux下如何使用split
答: 切割文件hello,以每个文件最大10MiB来切割,切割好的文件名前缀为hello.,后缀为二位的数字,切割之后的名字为hello.01,hello.02等等 split -b 10M - ...
- window下安装redis报错: creating server tcp listening socket 127.0.0.1:6379: bind No error
window下安装redis报错: creating server tcp listening socket 127.0.0.1:6379: bind No error 解决: 如果没有配置环境,在安 ...
- sonar runner的配置
#Configure here general information about the environment, such as SonarQube DB details for example ...
- Android -- 加载大图片到内存,从gallery获取图片,获取图片exif信息
1. 加载大图片到内存,从gallery获取图片 android默认的最大堆栈只有16M, 图片像素太高会导致内存不足的异常, 需要将图片等比例缩小到适合手机屏幕分辨率, 再加载. 从gallery ...
- 判断一个数是否是4的n次方
def is_Power_of_four(n): while n and not (n & 0b11): n >>= ) print(is_Power_of_four()) pri ...
- Qt5获取网卡/IP等信息
参考网址:http://blog.csdn.net/wjs1033/article/details/22697063 1.环境 Win7x64.Qt5.5.1(x86).vs2013_ultimate ...
- LTE空口协议——是空口3GPP协议 不是网络IP协议
[LTE基础知识]LTE空口协议分析 from:https://www.mscbsc.com/viewnews-102038.html控制面协议 控制面协议结构如下图所示. PDCP在网络侧终止于eN ...
- 从 TWAIN 设备中扫描图像
转自(http://yonsm.net/scan-images-from-a-twain-device/) 一.简介 TWAIN 数据源管理程序 (DSM) 工业标准的软件库,用于从静态图像设备提取图 ...
- R语言rJava包安装载入及JAVA环境配置
rJava 包的安装与载入 一般文本分词的教程都会贴出: install.packages("rJava") library(rJava) 来引导我们装载rJava包,运行inst ...
- 自定义控件---loadingView
自定义加载框,效果如图: 这个loadingView可以在图片下添加文案(加载中...),还可以自定义动画效果,自定义布局文件,屏蔽用户操作,点击返回键后隐藏. 库类中包含了一个LoadingDial ...