一类问题,典型问题一般如下:
1、给出超大文件,比如100T,每一行是一个访问ip/查询关键字等,计算频率最高的前100个。
2、给出超大文件,比如100T,第一行是一个值,计算第N个。
特点:
1、数据非常大,无法用内存加载。
2、数据无序。
3、结果顺序相关。
初步思路:一直在思考怎么用流式的一次遍历就直接出结果,无果。算法拼的就是经验,没搞过就很麻烦。
有效思路:hash划分,缩小量级,小量级下做有序处理,然后定位到具体的分片之后,重复这个过程,直到量级很小时,排序。
例如找出100T IP数据第1000个数,思路如下:
1、先计算一下内存使用。如果是1G,做hash计数,约1G/4字节=2^28方。
2、遍历一次文件,ip转换为整数,取前28位,在hash表计数,将将数据存入独立的文件。如果是字符串,可以正常取前28位(近4字符)。
3、统计之后,hash桶排序,如果足够离散,也可以直接遍历28bit位数,从命中开始找。确定第1000个在哪个桶。
比如按从小开始,桶计数分别是300,400,500,300,则第1000个在500桶中。
4、针对选定的桶,如果文件过大,重复上述过程,重复过程中注意忽略已经使用的前28位。对ip来说,只能取后4位了。
5、如果文件不大了,则直接排序,计算精确的位置,比如上面的数据,前3个桶相加是700,第1000是500桶的第300个。
对于前N问题,hash分片之后,每个桶分别独立计算前N个,然后再合并,排序,选择最终的结果。