海量数据处理问题
哈希切割top K问题
问题描述:
给一个超过100G大小的log file, log中存着IP地址, 设计算法找到出现次数最多的IP地址?
思路:
- 一个log file的大小为100G,计算机的内存有限,考虑将其切分成1000个小文件,
- 统计次数,我们可以考虑哈希表,相同的IP会映射到同一个小文件中,此时小文件的内存就不受到内存的影响,可统计IP出现的次数
- 使用哈希表,必然考虑哈希冲突的问题,如果哈希冲突过多,我们可考虑将其在进行哈希切分
具体步骤:
- 切分文件:100G的log file 切分成1000个小文件
- 计算位置:将每个文件中的IP映射到哈希表中,利用哈希函数将文件中的IP转化成整数,用公式表述为:file_id = hash(ip) % 1000
- 统计次数:统计每个小文件中IP出现的次数(注意:相同的IP会映射到同一位置),采用KeyValue模型,IP为key,Value为出现次数,每个文件中出现次数最多的IP就可统计出来
- 比较:在1000份小文件中,选出次数出现最多IP
变形:给一个超过100G大小的log file, log中存着IP地址, 设计算法找到出现次数最多的前K个IP地址?
思路:
-
统计前K个IP地址,可看作为TopK问题,具体做法为:
1.统计出1000份文件中每个文件里出现次数最多的IP
2.选取K个IP建立小堆,在依次取K之后的每一个IP与堆顶元素比较,如果大于堆顶元素,则覆盖堆顶数据,并进行向下调整,反之继续遍历源程序;
3.最后堆里的元素为出现次数最多的前K个IP
位图应用
问题1:
给定100亿个整数,设计算法找到只出现一次的整数
思路:
- 估算:100亿个整数,大小10G,一个整数所占4个字节,100亿个整数占内存为40G,我们的计算机内存显然不够,这时考虑使用哈希或者位图来解决
- 方法一:和上一题解法类似,将其分为100份,找每一份中只出现一次的整数,最后将100份文件进行汇总
- 方法二:采用位图,以位为单位存储这些数据,可用一个比特位来表示数字存在与否;统计出现一次或者多次,可采取使用2个比特位来表示数字出现的次数,例如:00不存在、01出现一次、10出现多次;统计出现一次的数字即可
- 二者方法比较:哈希效率快,计算结果较为精确,但所占空间较大;位图节省空间,100亿个整数,整数的范围大约为4290000000,所开出的空间为500M,大大节省了空间,但位图所得到的结果:找到的结果较为不准确一些
问题2:
给两个文件,分别有100亿个整数,我们只有1G内存,如何找到两个文件交集
思路:
- 题目限制,只有1G内存,故而由上题可以知道,所占内存太大,不可直接比较;我们知道,一个位图是500M,两个位图也才1G,这里采用位图比较合适
- 求文件的交集,可将其两个文件分别建立位图1和位图2,将两个位图进行&(按位与运算),得到的结果就是两个文件的交集
问题3:
1个文件有100亿个int,1G内存,设计算法找到出现次数不超过2次的所有整数
思路:
- 此题为问题1的变形,使用2个比特位来表示数字出现的次数,00不存在、01出现一次、10出现2次,11出现多次,统计时只统计00 01 10 的情况即可
布隆过滤器+哈希切分
问题描述:
给两个文件,分别有100亿个query,我们只有1G内存,如何找到两个文件交集?分别给出精确算法和近似算法
如何扩展BloomFilter使得它支持删除元素的操作
如何扩展BloomFilter使得它支持计数操作
思路:
精确算法:
- 估算:100亿个字节大约需要10G的内存,假设每个query所占10个Bit,100亿个query就需要100G的内存,显然计算机是存不下的
- 这里找交集,我们可以考虑使用哈希分割,具体做法如下:
1)将两个文件分别分成1000份的小文件,将问题转化为求这两个小文件划分出来的每个小文件的交集
2)将每个小文件的交集求出,整合成两个文件的交集
近似算法:
思路:
- 使用布隆进行过滤,将其中的某一个文件映射到位图当中,取另一文件的内容进行比对,如果不存在,那么就不是交集,如果存在,可视为交集
- 注意:虽然布隆在映射时会映射多个位置,但判断是否在位图中存在时还是可能出现误差,故此方法为近似算法
扩展思路:
- 布隆的删除和计数可归为一类问题,原本布隆是一个元素映射到多个位置上,这个位置上的值是一个Key,现在将其改为数据存在的个数,每当映射到相同的位置,该位置上的数进行加1,最后每个位置上的值表示出现某一元素映射到该位的次数
倒排索引
问题描述:
给上千个文件,每个文件大小为1K—100M。给n个设计算法对每个词找到所有包含它的文件,你只有100K内存
思路:
-
具体步骤
1)将你所要搜索的词进行分组,也就是获取到关键字,获取到关键字后去上千个文件中查找
2)对于每个文件,我们可以建立布隆,并在这些建好的布隆当中查看是否有我们已经获取好的关键字
3)进行布隆过滤后,我们考虑建立哈希表(拉链法),此时哈希表的存放的不是链表的地址,而是文件的地址,如果某一文件中含有关键字,就将其文件的地址存放在哈希表Key(关键字)对应位置
4)关键字在哈希表中映射的位置所保存的文件就是包含这个关键字的文件
-
倒排索引的思想(个人理解)
用来搜索某一单词或者关键字在某一文件或网页当中,例如:我们在百度上输入淘宝、博客等关键字,此时百度就会去各个网页当中搜索出现这两个关键字的网页,并且将关键字进行高亮,并且按照一定的排序规则将其网页的地址保存下来提供给我们
更多解释和倒序索引的过程可以点击链接:
http://blog.csdn.net/Gamer_gyt/article/details/47101351
http://blog.csdn.net/qq_18860653/article/details/78399983