map集合,list集合,数组,set集合——-都是在内存进行操作的,文件过大会造成内存溢出,根本无法处理。
一台机器原始性能有限,根据摩尔定律:每18-24个月硬件性能提升一倍,但是数据的增加速度远远大于硬件的提升速度。纵向扩展性能不是最终的解决方案。
我们考虑横向扩展,使用多台机器,分而治之。将原来的大文件分成很多个小文件,这很多个小文件分别在不同的机器上计算。
最终的解决方案:
- 1)将文件切分
- 2)每个机器进行统计自己机器上的数据的ip出现的次数
- 3)聚合统计 出现次数最多的ip
用流读取,放入set,再用set.contains(url)方法就能找到是否存在。
大文件:我们知道数组是由下标的,所有查询效率很高,但是增删就很慢,我们这里需要查询,所以可以利用数组来做。
- 首先有一个一个空的m位的位数组,所有位的值都为0。我们将url进行哈希:hash(url),得到每一个url的哈希code值,哈希code值,记做:index=哈希值%(分区数n)。则如果数组的index有值,该位就变为1。即用数组下标去记录(url哈希)以后并且(%分区)以后的数值,用0,1分别记录该值是否存在。
- 但是有一个问题:哈希的冲突本来就大,(%分区)以后冲突就更大,这样得出来的结果是不准确的。此时,我们可以设计k个哈希函数,这样一个url就有k个hash值,就有k个%分区以后的位值。只有这k个位置的值都为1,我们才判定这个url是存在的。
- 又有一个问题:哈希函数个数k为多少才是合理的呢?其实以上就是布隆过滤器的思想,根据公式:当 k=0.7 (实际长度/数组长度) 时,误判率最低。例如我们有1000000条数据,要放在10000长度的数组中,需要0.7*(1000000/10000)=70个哈希函数误判率最低
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) | 黑马程序员IT技术论坛 X3.2 |