Java使用极小的内存完成对超大数据的去重计数,用于实时计算中统计UV
来源:互联网 发布:市政工程算量软件 编辑:程序博客网 时间:2024/06/05 00:09
一直在想如何在实时计算中完成对海量数据去重计数的功能,即SELECT COUNT(DISTINCT) 的功能。比如:从每天零点开始,实时计算全站累计用户数(UV),以及某些组合维度上的用户数,这里的用户假设以Cookieid来计。
想想一般的解决办法,在内存中使用HaspMap、HashSet?或者是在Redis中以Cookieid为key?感觉都不合适,在数以亿计用户的业务场景下,内存显然也成了瓶颈。
如果说,实时计算的业务场景中,对UV的计算精度并不要求100%(比如:实时的监测某一网站的PV和UV),那么可以考虑采用基数估计算法来统计。这里有一个Java的实现版本 stream-lib:https://github.com/addthis/stream-lib
采用基数估计算法目的就是为了使用很小的内存,即可完成超大数据的去重计数。号称是只使用几KB的内存,就可以完成对数以条数据的去重计数。但基数估计算法都不是100%精确的,误差在0~2%之间,一般是1%左右。
本文使用stream-lib来尝试对两个数据集进行去重计数。相关的文档和下载见文章最后。
测试数据集1:
- 文件名:small_cookies.txt
- 文件内容:每个cookieid一行
- 文件总记录数:14892708
- 去重记录数:3896911
- 文件总大小:350153062(约334M)
测试数据集2:
- 文件名:big_cookies.txt
- 文件内容:每个cookieid一行
- 文件总记录数:547631464
- 去重记录数:190264959
- 文件总大小:12610638153(约11.8GB)
普通方法测试
所谓普通方法,就是遍历文件,将所有cookieid放到内存的HashSet中,而HashSet的size就是去重记录数。
代码如下:
指定使用10M的内存运行,命令为:
运行结果如下:
10M的内存,仅仅够存65000左右的cookieid,之后就报错,内存不够了。大数据集更不用说。
基数估计方法测试
采用streamlib中的基数估计算法实现ICardinality,对两个结果集的总记录数和去重记录数进行统计,代码如下:
- 测试数据集1
指定使用10M的内存运行,测试数据集1命令为:
运行结果如下:
- 测试数据集2
同样指定使用10M的内存运行,测试数据集2命令为:
运行结果为:
测试结果
测试结果来看,基数估计算法统计的结果中误差的确是0~2%,如果可以接受这个误差,那么这个方案完全可以用于实时计算中的不同维度UV统计中。
从运行结果图上可以看到,虽然指定了10M内存,但空闲内存(FreeMemory)一直在差不多7M以上,也就是说,5.4亿的数据去重计数,也仅仅使用了3M左右的内存。
相关下载
以上程序需要依赖stream-2.9.1-SNAPSHOT.jar,我编译好了一份,
点击下载stream-2.9.1-SNAPSHOT.jar
你也可以从官网中下载源码,编译。
相关文章:
http://blog.csdn.net/hguisu/article/details/8433731
http://m.oschina.net/blog/315457
- Java使用极小的内存完成对超大数据的去重计数,用于实时计算中统计UV
- 超大数据去重的处理办法
- MySQL中统计函数的使用
- 用于对值计数、求和及计算平均值的表达式
- 在SQLite中统计本周本月数据的代码实例
- sql中统计一列中重复的数据个数
- Redis中统计各种数据大小的方法
- 字符串中统计某字母的次数等【Java Base】
- Java中统计文章字符串字符个数的代码实现
- Java中统计字符串中各字符出现的次数
- Java数据内存去重
- Bloom Filter算法的Java实现(用于去重)
- Java中使用Socket完成简单的远程计…
- 015-Storm计算网站UV(去重计算模式)
- storm计算网站UV(去重计算模式)
- DSpace中统计功能的实现
- 在Vim中统计单词的个数
- HM中统计LCU的个数
- Jquery基础初探
- php连接sqlserver数据库服务器(或者称mssql数据库)的几种方法
- http://netfilter.org/ 读后感
- 图片文件上传以及图片文件流上传
- 原码补码反码以及位运算符
- Java使用极小的内存完成对超大数据的去重计数,用于实时计算中统计UV
- Hibernate单表开发步骤
- HTML第二课:表格、表单和框架
- Django笔记 CMS框架Mezzanine 2
- 异常
- JavaScript的变量作用域
- Ambari警报功能分析及源码解读
- Android 系统信息获取(CPU,RAM,ROM,Battery,SD-card,版本等)(转)
- 硬盘录像机数据恢复方法