首先熟悉一下进制转换
计算机最小单位 bit, 也就是 0 和 1
8 个 bit 为一个字节 byte
1024 个 byte 为 1 KB
1024 K 为 1 MB
1024 M 为 1 GB
…
解决方案:
(1) 采用Hash函数将 100G 的文件分为若干个小文件
例如: Hash(IP)%1024, 将其分为 1024 个小文件.其中Hash(IP)为每个小文件的编号.
(2) 逐个读取小文件, 对每个小文件建立一个 key 为 IP, value为出现次数的哈希表.将 IP 逐个放入哈希表中, 如果 IP 不存在, 就直接放进去, value 为 1, 如果 IP 已经存在了, 那么 value + 1, 这样统计出每个小文件中的 IP出现的次数.
(3) 到这里就已经知道了每个小文件中出现次数最多的 IP, 然后再用排序算法得到总的出现次数最多的 IP .
到这里, 还有几个问题需要思考.
第一, 切分是否均匀?
第二, 采用哈希表进行 IP 频率统计时的内存消耗问题.
另外, 还需要注意, Hash取模是一种等价映射,换句话说通过映射分割之后相同的元素只会分到同一个小文件中去。相同的IP通过Hash函数映射后只会被分到这1024个小文件中的同一个文件中.
解决方案:
100亿个整数有10G, 超出了我们的内存, 于是想到肯定还是要用到我们的哈希表, 位图等. 一般而言, 位图用一个bit位表示一个数字是否存在, 但是现在, 要表示一个整数出现的次数. 我们可以用两个bit位.
00 代表没出现
01 代表出现一次
10 11 代表出现一次以上
将这100亿个整数对应到这样的位图中, 找到所有01对应的整数, 即为只出现一次的整数.
就算用200亿个bit位, 也只占两个多G的内存.
解决方案:
首先还是一样, 100亿太大, 需要先切分, 将两个大文件且分为若干小文件, 然后对每个小文件进行处理, 将每个小文件中的字符串利用布隆过滤器保存, 然后再处理第二个大文件切分成的小文件, 处理时如果发现已经字符串已经存在, 那么就将此字符串放入交集文件中, 最后处理完毕即可得到两个文件的交集.
解决方案:
首先看两个概念:
正排索引: 由文件的 ID 找到对应的文件内容
倒排索引: 相反, 由文件内容找到对应的文件 ID
1, 首先, 我们对每个文件建立一个布隆过滤器, 将文件中的词对应到布隆过滤器中, 此时我们就得到了上千个布隆过滤器, 每个文件对应一个布隆过滤器.
2, 将要查找的词在一个个布隆过滤器中查找, 如果发现某个布隆过滤器中存在这个单词, 那么就知道了哪个文件存在这个词.
对于海量数据问题, 首先应该想到先切分, 大事化小小事化了.
然后利用哈希表, 位图, 布隆过滤器等, 如果需要还可以借助排序算法等.
核心思想就是分而治之.