海量数据处理——基于hash的常见问题总结

一、信息压缩处理
问题1:如果有40亿个数(不重复无符号整数),需要知道某个数是否在这40个亿中?
答:如果利用hash表来查找,需要 int[] array=new int[40亿],用这40亿个数作为下标初始化一个数组,各个值为0,然后遍历数组,下标等于这个数的位置存1,根据所有位置存的是0还是1就能知道某个数是否存在了。
40亿×4字节=160亿字节,每个位置只需要存0或1 ,用4字节来存太浪费空间。
由此引入位图:
所谓的位图,就是利用 1 bit保存0或1 (存在或者不存在的问题)
int[] bitArray=new int[10]
10*32 bit 可以判断320个数中是否存在的问题
位图的整体思路:压缩空间

问题2:如果需要判断王者荣耀的某玩家是否在黑名单里,然后确定是否进行封号,该设计怎样的算法?
比如黑名单为 {张三,李四,王五,赵六,…} 不是无符号的整数但是是海量的,这时就不能保证不重复,不能使用位图解决
这就需要引入布隆过滤器:
布隆过滤器原理: 将所有的用户利用多个哈希函数得到多个下标,将这多个下标处的值设置为1,然后使用这多个哈希函数对要查找用户进行处理得到下标,如果该用户得到的所有的下标处的值都为1,则这个用户在黑名单里,只要有一个得到的下标处的值为0,则说明这个数不在这个数据集里.
缺点:某用户可能不在黑名单里,但是得到的值为1 被进行了封号处理.(可能性小,概率事件)

二、分段处理
问题1:一个日志文件中保存了很多IP地址,问如何找到出现次数最多的IP地址?
解决思路: 1.如何获取每个IP地址的出现次数–Map解决
2.如何找到出现次数最多的IP–遍历Map,找max位置

伪代码:
InputStream is=new FileInputStream(“ip.txt”);
Scanner scanner=new Scanner(is);
Map map=new HashMap<>();
while(scanner.hasNextLine()){//假设一行一个IP地址
String ip=scanner.nextLine();
int count=map.getOrDefault(ip,0)
map.put(ip,count+1);
}
//再遍历map中的所有key-value,找到count最大的一组
String maxIp=null;
int maxCount=-1;
for(Map.Entry entry:map.entrySet()){ //entrySet是key-value对,Set里面的类型是Map.Entry
String ip=entry.getKey();
int count=entry.getValue();
if(count>maxCount){
maxCount=count;
maxIp=ip;
}
}
maxIp就是出现次数最多的IP

如果IP数量太大了,大到map在内存中存不下了,上述办法失效.

核心思路:分段处理,将原来的大文件,分成多个小文件分别处理
如何分段?相同的IP被分到一起–利用hash函数分段
分好之后,先依次对每个小文件选出次数最多的IP和出现次数,再在所有文件中选出最优解.

如何设计这个hash函数?
比如:分成10个文件,得到的下标为[0,10)
hash函数1:取IP地址的最后一位 192.168.10.0 取0
hash函数2:把IP地址中所有值相加v=192+168+10+0 取v%10
hash函数3:v=1921000+168100+10*10+0 取v%10

哈希函数可以设计很多,但是性能不一定好

问题2:给定100亿个整数,设计算法找到只出现一次的整数?
问题3:给定两个文件,分别有100亿个整数,只有1G内存,如何找到两个文件的交集?
万能方法:分段处理

这类问题,还可以从信息压缩的角度思考–位图
对于问题2:要找出只出现一次的整数.
某个数出现的情况有三种:不出现/出现一次/出现超过一次
1 bit只能存二元信息,三元信息需要2 bit,分别用00/01/11来表示,
如果有40亿个数只出现了一次,需要40亿2 bit =10亿字节,如果按常规思路,一个数用4个字节表示,需要40亿4字节=160亿字节,很明显这种方法节省了空间.

对于问题3:要找出在两个文件中都出现的数.
某个数出现的情况有四种:都不出现/只在a出现/只在b出现/都出现,
用2 bit表示四元信息,以上情况分别用00/10/01/11来表示

注意:
一定是处理数字的问题,才有可能用空间压缩的办法解决
不是处理数字的问题,可以试试布隆过滤器。

海量数据处理问题总结:
1.分段处理–核心在于文件怎么分–按hash函数分–万能方法
2.信息压缩处理–优点是实现简单,但是有使用范围

  • 位图
  • 布隆过滤器(得到的结果是概率性的)

你可能感兴趣的:(Java)