算法专题之bitmap与布隆过滤器 ----如何快速处理海量数据
Posted 厚朴HOPE工作室
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了算法专题之bitmap与布隆过滤器 ----如何快速处理海量数据相关的知识,希望对你有一定的参考价值。
前言
相信大家都知道,在服务器中的文件往往都是以TB为计算单位的,如果要批量处理这些数据,不通过一些特别的方法,往往将会非常耗时,因此,该篇文章将对常见的方法进行一个总结。
在描述方法之前,不妨先想一道面试题:
5TB的硬盘上放满了数据,请写一个算法将这些数据进行排重。如果这些数据是一些32bit大小的数据该如何解决?如果是64bit的呢?
其中排重是指排除掉重复的部分,也就是说,处理后,这些数据要保证没有任何重复部分。
小编看着道题的第一反应:
5TB,从开始位置每个文件依次对比,判断是否重复,如果重复就把重复的部分删除,时间复杂度最高O(n^2)
不过,这样时间成本太高了!不行得换个方法。
用字典树处理,把每个文件都放到字典树中存储,重复的部分会在存储时遇上,自动消除重复,最后再把树中的内容提取出来就可以了。
看起来时间复杂度不高,只有O(nlog(n)),但是空间复杂度非常高,而且怎么将每个文件分块存储,分块分多大才能保证存储时间最小,都是问题,而且分块越多,由于字典树需要用指针指向下一个位置,所以空间成本也非常的高。
综上来看,这也不是一个非常适合的方法。
那怎么办呢......
首先,我们可以尝试一下bitmap方法,首先我们都知道计算机中数据是以2进制存储的,也就是说每位都只能有1和0两个可能值
那么,我们不妨用一位来代表一个数据是否存在过,用1来代表出现过,0来代表没有出现过
接着我们可以思考一下,这些数据如果是32bit的,那么他们所存储的数据所有可能的取值为2^32。
在这种情况下,由于只需要一位来代表一个值,所以每个数据所需要存储的空间为1bit,总共需要存储的空间就为2^32bit=512MB,远小于5TB
接着,我们以该空间中第一个位代表0,第二个位置代表1,第三个位置代表2,依次下去,对每个数据,直接对其二进制结果求对应的位置,并判断是否该位置数值为1,如果是1代表数据已经出现过了,那么不需要再修改,如果没有出现过就将其数值改为1
最后,全部数值判断完毕后再对这512MB中的内容进行处理,将所有数值为1的位置对应的数据输出即可,
这样处理,会使得整个事件复杂度接近O(n),空间上占用也比字典树的方法要小很多
当然,这个方法也是有缺点的,如果把5TB的数据改为5MB的数据,那么其实使用bitmap依然需要512MB的存储空间,这比其他方法所需要的内存空间要大很多,而且这个方案只能存储数据的数值信息,所以在很多地方都有限制。
到这里就算完成了?
不不,如果我们使用64bit大小的数据,用bitmap还能处理吗?我们按照之前的流程,先开个空间给bitmap,2^64bit=2EB,这是什么概念呢,1EB=1024PB=1024*1024TB,而一般服务器的存储空间能够上1PB的非常少,就算使用专业存储也远远无法存储这么多数据
所以这种情况时就不能使用bitmap了,那我们应该怎么处理呢?
这时就要用到布隆过滤器(Bloom Filter)了
↓↓↓
如果说Bitmap对于每一个可能的整型值,通过直接寻址的方式进行映射,相当于使用了一个哈希函数,那布隆过滤器就是引入了k(k>1)k(k>1)个相互独立的哈希函数,保证在给定的空间、误判率下,完成元素判重的过程。
下图中是k=3k=3时的布隆过滤器。
x,y,z经由哈希函数映射将各自在Bitmap中的3个位置为1,当w出现时,仅当3个标志位都为1时,才表示w在集合中。图中所示的情况,布隆过滤器将判定w不在集合中。
使用布隆过滤器与使用bitmap不同,布隆过滤器存在一定的误差,但是误差往往非常的小,当我们使用64bit的数据时,5TB实际的存储数据量约为2^34个,如果我们将用于判断的空间设定为16*2^32,那么我们实际上申请的空间为2^38bit=32GB,这个时候经过计算,误差率上限大概为0.0005,由于误差概率的上限非常的低,所以很多情况下我们都会愿意使用布隆过滤器。
布隆过滤器通过引入一定错误率,使得海量数据判重在可以接受的内存代价中得以实现。
经过数学公式推导,随着集合中的元素不断输入过滤器中(原始数据量增大),误差将越来越大。但是,当Bitmap的大小(指bit数)足够大时,比如比所有可能出现的不重复元素个数还要大10倍以上时,错误概率是可以接受的。
经过上面一番学习
再面对这道面试题时
你们会使用什么方法做呢?
END
以上是关于算法专题之bitmap与布隆过滤器 ----如何快速处理海量数据的主要内容,如果未能解决你的问题,请参考以下文章