大数据计算:如何仅用1.5KB内存为十亿对象计数

摘要:AddThis的数据分析副总监Matt Abrams在High Scalability上发表了一篇文章,介绍了他们公司如何应对大数据。Matt Abrams表示,AddThis仅仅用了1.5KB内存的内存就计算了十亿个不同的对象,这与他们所使用的计算方法分不开的。

AddThis(前身为Clearspring)的数据分析副总监Matt Abrams在High Scalability上发表了一篇文章,介绍了他们公司如何应对大数据。在这篇文章中,AddThis仅仅用了1.5KB内存的内存就计算了十亿个不同的对象,Matt Abrams主要向我们详解了他们公司在处理过程中使用的方法。

以下为文章全文:

在AddThis,我们喜欢统计数据。对一组中不同元素(也称为“基数”)的数量进行计数,当其数量很大时,这是一个挑战。

为了更好地理解确定的大型成套基数的挑战,让我们想象一下,在你的日志中有一个16个字符的ID,并且你想计算不同ID的数量。这里有一个例子:

4f67bfc603106cb2

16个字符需要用128位来表示。6万5千个ID将需要1MB的空间。我们每天收到30多亿个事件,每个事件都有一个ID。这些ID需要3840亿位或45GB的存储。而这仅仅是ID字段需要的空间!为了得到我们日常活动中的ID基数,我们可以采取一个简单的方法。最简单的想法是使用内存中的哈希集合,其中包含在输入文件中看到的独特的ID列表。即使我们假设3条记录中有1个是唯一的,哈希集合仍需要119GB的RAM,不包括Java需要在内存中存储对象的开销。你需要一台配备几百GB内存的机器来计算不同的元素,并且这只是计算一天的独特ID的成本。如果我们想要数周或数月的数据,这个问题只会变得更加困难。我们身边当然不会有一台配备几百GB内存的空闲机器,所以我们需要一个更好的解决方案。

解决这一问题的常见办法是使用位图。位图可以用来快速、准确地获取一个给定的输入的基数。位图的基本思路是使用哈希函数映射数据集到一个位字段,在位字段里输入的独特元素映射到该字段中的一个位。这产生零碰撞,并减少需要计算每个独特元素到1位的空间。虽然位图大大减少了对空间的要求,但当基数是非常高或你对非常多的不同的组进行计数时,它们仍然有问题。例如,如果我们想要使用位图计数十亿,你将需要十亿位,或需要每个约120 MB的计数器。稀疏的位图可以被压缩,以获得更多的空间效率,但也并不总是有帮助的。

幸运的是,基数估计是一个热门的研究领域。我们已经利用这项研究提供了一个开源实现的基数估计、集员资格检测和top-k算法。

为了了解算法占用的空间与精确度之间的关系,我们用三种不同的计算方法在所有莎士比亚的作品计数了不同单词的数量(90万)。请注意,我们的输入数据集有额外的数据,所以基数高于这个问题答案的标准参考。我们使用的三种技术是:Java HashSet、Linear Probabilistic Counter以及一个Hyper LogLog Counter。这里是结果:

该表显示,我们只使用512字节的空间就可以进行计数,并且误差在3%以内。相比之下,HashMap的计数准确度最高,但需要近10MB的空间,你可以很容易地看到为什么基数估计量是有用的。在实际应用中精度并不是很重要的,这是事实,在大多数网络规模和网络计算的情况下,用概率计数器可能会节省巨大的空间,这是真的。

线性概率计数器

线性概率计数器是高效的空间,并且允许实现者指定所需的精度水平。该算法在注重空间效率时是很有用的,但你需要能够控制你结果里的误差。该算法运行需要两步:第一步,在内存中分配一个初始化为都为0的位图,随后哈希函数被应用于输入数据中的每个条目,哈希函数的结果将映射条目到位图的一个位上,该位设置为1;第二步算法对空位的数量进行计算,并使用这个数字输入到下面的公式来获得估计。

n=-m ln Vn

在方程中,m是位图的大小,n是空位和映射的大小的比率。需要重点注意的是原始位图的大小,可以远小于预期的最大基数。小多少取决于你能忍受多少错误的结果。因为位图的大小、m,小于不同元素的总数,将会有碰撞。这些碰撞都可以节省空间,但同时也造成了错误的估计。所以通过控制原始映射的大小,我们可以估算碰撞的次数,因此我们将在最终结果中看到误差量。

Hyper LogLog

顾名思义,Hyper LogLog计数器的特点是,你仅需要使用loglog(Nmax)+一个常数那么多位就可以对Nmax进行计数。如线性计数器的Hyper LogLog计数器使设计人员能够指定所需的精度公差,在Hyper LogLog的情况下,这是通过定义所需的相对标准偏差和你期望要计数的最大基数。大部分计数通过一个输入数据流、M,并应用一个哈希函数设置h(M)来工作。这将产生一个S = h(M) of {0,1}^∞字符串的可观测结果。通过分割成m子字符串的哈希输入流,并为每个子数据保持m的观测值扩展了Hyper LogLog。使用额外的观测值的平均值,产生一个计数器,其精度提高为m的大小增长,只需要一个在输入集的每个元素上恒定要执行的操作数目。其结果是,这个计数器可以仅使用1.5 kb的空间计算精度为2%的十亿个截然不同的项。与执行 HashSet所需的120 兆字节进行比较,这种算法的效率变得很明显。

合并分布式计数器

我们已经证明了使用上面描述的计数器我们可以估算大集合的基数。但是,如果你的原始输入数据集不适合于单台机器,你能做些什么?这正是我们在AddThis所面临的问题。我们的数据分散在数百台服务器上,并且每个服务器只包含整个数据集子集的一部分。这就是事实,我们可以合并一组分布式计数器的内容,这是至关重要的。这个想法有点令人费解,但如果你花费一些时间去思考这个概念,就会发现其与基本的基数估计值相比并没有太大的不同。因为计数器代表映射中的位作为基数,我们可以采取两个兼容计数器并将其位合并到单一的地图。这个算法已经处理碰撞,所以我们可以得到一个基数估计所需的精密,即使我们从来没有把所有的输入数据到一台机器。这是非常有用的,节省了我们在网络中移动数据的大量时间和精力。

总结

希望这篇文章能帮助你更好地理解这个概念和概率计数器的应用。如果估计大集合的基数是一个问题,而你又碰巧使用一个基于JVM的语言,那么你应该使用stream-lib项目——它提供了其他几个流处理工具以及上文所述的算法的实现。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/449893.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C#关键字的个人理解与注释

C#关键字注释:abstract:抽象as:类型转换(返回转换结果)base:基类bool:布尔类型break:条件中断语句byte:字节case:条件语句catch:异常捕获后执行ch…

Linux declare命令、Linux tail 命令

前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到教程。 Linux declare命令用于声明 shell 变量。 declare为shell指令,在第一种语法中可用来声明变量并设置变量的属性([rix]即为变…

详解Nagios配置文件的逻辑关系

1.主配置文件/usr/local/nagios/etc/nagios.cfg a.定义了用户和组 b.定义了某些具体参数 c.定义了配置文件和可以存放配置文件的文件夹 d.通过开头的#号去注释选项以达到关闭配置的效果 e.更改配置后,可以通过命令 /usr/local/nagios/bin/nagios –v /usr/local/na…

10 步让你成为更优秀的程序员

这篇文章要介绍的,是我作为专业程序员这些年来学到的能真正提高我的代码质量和整体工作效率的10件事情。 1. 永远不要复制代码 不惜任何代价避免重复的代码。如果一个常用的代码片段出现在了程序中的几个不同地方,重构它,把它放到一个自己的函…

《流浪地球》 电影全集

《流浪地球》 电影全集 《流浪地球》是由郭帆导演,吴京特别出演,屈楚萧、李光洁、吴孟达等人主演的科幻片《流浪地球》宣布定档2019大年初一。同时,影片发布了一款定档预告片,预告片开头传来一段广播声音:“太阳急速老…

kotlin之plus、copyOf、reverse、forEach、filter、map、reduce、fold等函数解释和使用

kotlin之::函数调用、plus(增加元素)、copyOf(复制数组)、reverse(翻转数组)、forEach(遍历数组)、filter(过滤数组)、map函数操作及扩展、reduce函数、fold函…

linux 常用命令 杂记

前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到教程。 1.cat cat 命令用于连接文件并打印到标准输出设备上。 使用权限 所有使用者 2.Linux chgrp命令用于变更文件或目录的所属群组。 3.Linux…

C程序员要学C++吗?

最近网友问到这一问题,但我更希望被问的是“C程序员需要学面向对象编程吗?”,那就让我先从回答这一问题开始,并做适当的扩展。 就我的成长经历来看,C程序员必须学习面向对象编程!面向对象编程语言有其天然的…

追女生心理研究(本人母胎单身,就是想做准备,并无其他意思)

聊天话题: 1。兴趣爱好:美食,旅游,宠物等 2。现在和曾经的自己,分享自己的经历 3。我变成我们,未来规划 4。分析隐私,比如一些小秘密 5。价值观,对未来的规划等 聊天话题技巧 …

dlopen 和 dlsym 动态调用函数

Linux/unix 提供了使用 dlopen 和 dlsym 方法动态加载库和调用函数,这套方法在 macOS 和 iOS 上也支持。dlopen 打开一个库,获取句柄。dlsym 在打开的库中查找符号的值。dlclose 关闭句柄。dlerror 返回一个描述最后一次调用dlopen、dlsym,或…

通过腾讯地图服务获取行政区划信息

接口说明地址: https://lbs.qq.com/webservice_v1/guide-region.html 以下是源代码及表创建脚本。 源码及相关文件下载转载于:https://www.cnblogs.com/challengesoflife/p/10405366.html

情感学习聊天方法

1.非正常聊天法 出人意料的聊天技巧,展示幽默感,让对方对自己产生兴趣 比如对方说:你的朋友圈好多美女啊。回答还好了,没有了。场面会一度尴尬 但可以这么说:你这样是在间接夸自己是美女。或者:还好啦&a…

面向对象设计的优点

一旦明白了软件设计的真谛(参见《软件设计的真谛》),我们就更能理解面向对象设计的优点。简单说来,它更便于我们在软件中构建更真实的虚拟世界。 首先,对象的引入方便了在软件虚拟世界中模拟现实世界。现实世界是由很…

利用SVD-推荐未尝过的菜肴2

推荐未尝过的菜肴-基于SVD的评分估计 实际上数据集要比我们上一篇展示的myMat要稀疏的多。 from numpy import linalg as la from numpy import * def loadExData2():return[[0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 5],[0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 3],[0, 0, 0, 0, 4, 0, 0, 1, 0,…

在图像中截取小图并保存

实现以横向步长step_row、纵向步长step_col&#xff0c;在一幅大图上剪裁宽度为width、高度为height的小图像&#xff0c;图像命名形式为“数字(递增)_大图名”格式&#xff0c;将小图保存在argv[6]的文件夹中。 #include <opencv2/opencv.hpp> #include <string> …

Linux 文件与目录管理、ls、cd、pwd、mkdir、rmdir、cp、 rm

见&#xff1a;http://www.runoob.com/linux/linux-file-content-manage.html我们知道Linux的目录结构为树状结构&#xff0c;最顶级的目录为根目录 /。 其他目录通过挂载可以将它们添加到树中&#xff0c;通过解除挂载可以移除它们。 在开始本教程前我们需要先知道什么是绝对路…

软件设计的真谛

假设我们身边的一切都是用制造材料加以描述的&#xff1a;“空调”不是“空调”&#xff0c;而是“由金属和塑料做成的物体”&#xff1b;“书”不是“书”&#xff0c;而是“由纤维和墨做成的物体”。沟通时我们也不用“空调”和“书”这样的词汇&#xff0c;而是“金属和塑料…

脱单特质

1.上进心 所有人都想过好日子&#xff0c;物质不行&#xff0c;一定要有上进心&#xff0c;可以做出未来给予 2.外在形象 注重打理外在形象&#xff0c;所有人都是爱美的 3.无法控制自己&#xff0c;同时不去了解女生 控制住自己&#xff0c;才有更多的时间去了解和思考女…

云栖社区云栖号(团队博客)攻略【2018版】

云栖社区云栖号是什么&#xff1f; 这是一个为技术团队打造的专区&#xff08;小站&#xff09;&#xff0c;团队成员的技术文章将在这里汇总&#xff0c;可以帮助团队沉淀优质技术内容、打造技术品牌和影响力等。 云栖号申请条件 点击https://yq.aliyun.com/teams页面右侧的【…

1030 完美数列 (25 分)二分

1030 完美数列 &#xff08;25 分&#xff09;给定一个正整数数列&#xff0c;和正整数 p&#xff0c;设这个数列中的最大值是 M&#xff0c;最小值是 m&#xff0c;如果 M≤mp&#xff0c;则称这个数列是完美数列。 现在给定参数 p 和一些正整数&#xff0c;请你从中选择尽可能…