现在的位置: 首页 > 综合 > 正文

海量数据统计通解之 偌大的数据,“弱小”的内存——逐个击破!

2013年10月20日 ⁄ 综合 ⁄ 共 1369字 ⁄ 字号 评论关闭

通常,海量数据统计上都存在一个普遍问题就是希望内存占用很低。为什么要这么做?因为数据海量,海量到你再有钱也买不了能装下他们的内存。

比如这个:

有a,b两个文件,每一个里面有50亿个URL,每一个URL为64字节。让你找出来同时在a,b两个文件中的URL。内存只有4g。

我们先来看看4g的内存就全装URL能装多少,能装67108864个URL,是六千多万。在这样的情况下, 你就是再来40g也不用,更不要说32位windows还有2g是留给操作系统的。

所以,要解决这样的问题,我们就要把文件分块。至少分块到能加载到内存中的大小,然后每次都处理这样一小块数据。
这样的策略我就戏称它为逐个击破(也有很多网文称之为分而治之)。

要清楚文件得分块,是完成了第一步。第二部就是,文件怎么分块。

通常海量数据的统计中都是:找出两个/多个文件相同的数据(求交集),根据数据出现的频度排序,找到最频繁的XXXXX什么的。总结归纳一下,就是让你先要把具有同样特征的数据放到一起,然后统计数量。

同样的特征有很多种,比如URL的域名相同,那么你就可以说这是同样的特征,再比如IP地址的统计,IP子网相同,这也是同样的特征。

那么,这些同样特征中更同样的特征就是:某个HASH函数的HASH VALUE相同。比如SHA1值,比如MD5值。

无论如何,我们现在把都有同样特征A的数据都归纳到一个文件当中,持有特征B的文件归纳到另一个文件里,于是,我们在这些具有同样特征的数据间进行统计就等于降低了问题的规模。数据根据特征进行分类,是一个O(n)时间量级的工作。

文件现在被我们打碎了,但是我们突然发现,文件被打的太碎了,都成渣了。比如我们假设将所有SHA1相同的数据放到一个文件里。SHA1值有多长呢?20字节,那么不同的SHA1 值就会存在于不同的文件中。这可能会导致创建多少个文件呢?最坏的情况下是2的160次方个文件。我估计你硬盘里哪一天看到有这么多文件你一定会无语个数十分钟。

这时,你就应该考虑控制一下文件的大小,不要太小,不要太大。由于在题目中允许你使用4g的内存,那么a,b两个数据来源进行比较,则每一个需要2g。2g至少容纳多少个URL呢?3千多万。50亿对应这近4千万的数据是多少个文件呢?125个文件。当然了,我们是在没必要把内存卡的那么紧,我们还可以再宽松一些,分成1024个文件好了。于是上面的SHA1 HASH值就会对1024取模,余数相同的放在一起。恩,现在看起来reasonable多了。

总结一下:我们先要把具有相同特征的数据归纳到一起(比如HASH VALUE相同),然后找一个合适的文件大小和数量(比如1024)。最后,具有相同特征的数据全部都放在了一起。如果你要求交集,那么就是a,b文件在打碎后,具有相同特征的子文件a' 和b'之间的操作了。内存能放得下,而且可以用HASH表来存储A里面出现的URL,然后再让B同样HASH,如果相应位置上标记了存在,那么结果就输出这条记录,是O(n)的时间复杂度。

逐个击破的最终总结就是:你首先要把海量数据按照特征归纳到一起,然后在这些具有特征的数据之间进行操作。如果说要用一句话概括全文,那就是:

长的变短(长字符串可以用HASH值代替它,从而缩短至20个字节或者40个字符<对SHA1来说>),大的变小(文件分割)

抱歉!评论已关闭.