海量数据处理问题!
海量数据处理问题!
月伴飞鱼假如有一个1G大小的文件,文件里每一行是一个词,每个词的大小不超过1Byte,要求返回出现频率最高的100个词。
内存大小限制是10M。
由于内存限制,无法直接将大文件的所有词一次性读到内存中。
可以采用分治策略,把一个大文件分解成多个小文件,保证每个文件的大小小于10M。
- 进而直接将单个小文件读取到内存中进行处理。
第一步
首先遍历大文件,对遍历到的每个词x,执行
hash(x) % 500
。将结果为i的词存放到文件
f(i)
中,遍历结束后,可以得到500个小文件,每个小文件的大小为2M左右。
第二步
接着统计每个小文件中出现频数最高的100个词,可以使用
HashMap
来实现,其中key
为词,value
为该词出现的频率。
- 对于遍历到的词x,如果在
map
中不存在,则执行map.put(x, 1)。
- 若存在,则执行
map.put(x, map.get(x)+1)
,将该词出现的次数加1。
第三步
在第二步中找出了每个文件出现频率最高的100个词之后,通过维护一个小顶堆来找出所有小文件中出现频率最高的100个词。
遍历第一个文件,把第一个文件中出现频率最高的100个词构建成一个小顶堆。
如果第一个文件中词的个数小于100,可以继续遍历第二个文件,直到构建好有100个结点的小顶堆为止。
继续遍历其他小文件,如果遍历到的词的出现次数大于堆顶上词的出现次数。
可以用新遍历到的词替换堆顶的词,然后重新调整这个堆为小顶堆。
当遍历完所有小文件后,这个小顶堆中的词就是出现频率最高的100个词。
主要思路如下:
采用分治的思想,进行哈希取余。
使用HashMap统计每个小文件单词出现的次数。
使用小顶堆,遍历步骤2中的小文件,找出词频Top100的单词。