海量数据处理介绍
所谓海量数据,其实就是数据量比较大处理起来不大方便。举个简单的例子,中国人口13亿,如果需要对这么多人进行出生时间,籍贯,家庭住址等进行存储查找。另外一个例子就是,搜索关键字的排名等。这些问题面临的最大问题就是数据量很大。
海量数据处理主要从时间和空间两个维度来考虑。
* 时间角度: 为了存储数据,必须能够很快的找到空闲空间进行存储;为了查找分析数据,必须能够很快的找到对应的存储空间。也就是说时间复杂度必须足够小。通常必须为
O(a∗logN)
。
* 空间角度:数据量比较大的时候,分而治之,大而化小是唯一的选择之道。因为当数据量比较大时,是不可能将全部数据装载到内存里的,更多的情况是大而化小后,存储在硬盘存储器中。每次只处理一个小文件/小数据。各个击破。
海量数据处理方法
- 分而治之/Hash映射+Hash统计 + 堆/快速/归并排序
- 双层桶划分
- Bloom filter/Bitmap
- Trie树/数据库/倒排索引
- 外排序(Merge sort)
- 分布式处理之hadoop/mapreduce
海量数据例子和应用
方法一、分而治之/hash映射 + hash统计 + 堆/快速/归并排序
海量日志数据,比如某天访问某网站最多次的IP地址
(1). 分而治之/Hash映射。内存的大小是有限的,所以将访问的IP值通过Hash映射后存储到不同的文件中去。计算Hash值 indx=H(key)
(2). Hash统计。存储到文件中后,通过Hash_map的方式统计IP的频率。
(3). 堆/快速排序。统计完每个文件出现最大频率的IP后,用快速排序得到出现最多次的那个IP。时间复杂度要求是 O(NlogN) ,所以堆排序或者快速排序比较适用。
具体实施:首先32位IP最多有 232 个地址。如果存储到1024个文件中去,一个文件的大小将大大缩小。如果选择合适的Hash函数,IP地址在各个文件中的分布将比较均匀。然后对1024个文件中的IP地址统计他们的出现频率,这个工作其实可以在Hash_insert的时候进行完成。通过快速快速排序可以找出每个文件中出现频率最高的那个IP。然后在1024个出现频率最高的IP中找到最大的那个。
代码实现可以将http://blog.csdn.net/wxcwys/article/details/46801923 中的代码稍加修改就可以得到。Key就是IP地址,然后data就存储出现的频率,每次insert的时候都递增。有一个1G大小的一个文件,里面每一行是一个词,词的大小不超过16字节,内存限制大小是1M。返回频数最高的100个词
(1).分而治之Hash映射。遍历文件,将每个词进行Hash map,然后按照Hash索引存储文件。文件的个数可以为5000,一般选取4096使除法运算简化为移位运算。记文件为( f0,f1,...,f4095 )。这样,每个文件大大小约为200K,都小于内存1M的大小。如果由于聚结,文件的大小大于1M,那么进行再散列,保证每个文件的大小小于1M。
(2).Hash统计。Hash map的方式统计每个文件中出现的词以及其频率。其实这个动作可以在分割文件的时候就可以完成。
(3).堆/归并排序。遍历所有的文件,取出出现频率最高的100个词(堆排序),这100个词及其出现频率再存储成4096个文件。对这4096个文件进行归并排序。给定a、b两个文件,各存放50亿个url,每个url各占64字节,内存限制是4G,让你找出a、b文件共同的url
文件的大小为5G*64=320G,远远超过内存的限制4G,因此不可能load到内存中再进行处理。
(1).Hash映射。用相同的Hash函数对文件a,b进行处理。具有相同Hash value的url存储到相同的文件中去,记为( a0,a1,...,a1023 )和( b0,b1,...,b1023 )。不同文件中不可能有相同的url,也就是说 ai 与 bi 是一一对应的。
(2).Hash统计。统计每对小文件中相同url时,可以先将 ai load到内存中,然后对 bi 进行遍历,看是否在 ai 中(Hash set的方式),直到所有url遍历完。将相同的url存储到文件中就完成了任务。
方法二、Bloom filter/Bitmap
在2.5亿个整数中找出不重复的整数,注,内存不足以容纳这2.5亿个整数
给40亿个不重复的unsigned int的整数,没排过序的,然后再给一个数,如何快速判断这个数是否在那40亿个数当中
方法三、Trie树/数据库/倒排索引
方法四、外排序
方法五、分布式处理 Mapreduce