海量数据处理

1、 海量日志数据,提取出访问次数最多的IP

2^10 = 1024 = 1k 千

2^20 = 1M 百万

2^30 = 1G 十亿

2^32 = 4G

传统方法:分治 + Hash

(1)一行一行处理日志,提取出IP,并对IP进行Hash取1024的模,也就是将 2^32 = 4G 个IP 分散到 1024 个小文件中,每个文件中包含的IP不超过 4M 个,一个文件的大小应该不会超过内存的限制,当然,即使超过了也没有关系。

(2)统计每个小文件中的频次最高的IP。

如果使用HashMap,以IP为key,长度按20字节计算;value使用 long, 8个字节,所以这个HashMap的大小不会超过 4M * 28 = 112M,完全可以放在内存中。

所以可以从文件中一行行读出IP,对value加1。

(3)统计出1024个小文件中频次最高的IP后,再从中选出最高的那一个就行了。


MapReduce方法

这个需求其实类似于WordCount,然后WordSort。

a. WordCount阶段

(1)Map阶段:HDFS的Block是128M的,一个Block给一个Mapper处理,对于这种计算量不大的应用,一个节点上启动100个Mapper都行,所以输出 < IP, 1 >这样的输出很容易。

(2)分区Partition 取1024个,Reducer也有1024个。Reducer输出的结果就是1024个小文件,文件中每一行就是 < IP, 频次> 对。

b. WordSort阶段

主要利用MapReduce的排序特性。Mapper的输出在本地缓存中就有做一次排序,Reducer向多个Mapper取数据的时候也会再排序一次,所以,进入Reducer阶段的时候,输入是有序的。

海量数据处理_第1张图片

(1)Mapper,将 < IP, 频次 > 反转为 < 频次, IP >

(2)Reducer的输入将会是 < 频次, (IP1,IP2,.... , IPn) >,而且是经过排序的。所以,Reducer只需要对这个输入进行打印就行了,那么每个partition文件的最后一行就是这个文件中频次最高的IP。

(3)从局部最大值中选出全局最大值。


全排序

如果要在MapReduce中就做好全排序的话,只需要保证分区有序就行了,即保证Partition1的最大值小于Partition2的最小值。如果手动指定分区区间,比如 [1, 1w]给 Reducer1,[1w, 10w]给Reducer2,会造成的问题是分布不均,导致某些Reducer的需要处理的数据量远高于其他Reducer。

解决方案是先利用MapReduc的Sample采用功能对数据集进行采样,然后统计各个区间的数量,做成直方图,再根据直方图划分分区。


2、搜索引擎记录检索串,1-255字节,总共不超过3百万个,求 TopK

(1)使用HashMap统计频率。百万就是M级别,3百万个检索串,占用内存大概是 3M * 255 = 765M,不超过1G。所以在内存中使用HashMap是可以的。

(2)借助堆结构找出TopK。维护一个K大小的最小堆,然后遍历300万的检索串,分别与根元素比较。时间复杂度是 N*LogK

你可能感兴趣的:(Algorithm,大数据)