最近看了July的一些关于Java处理海量数据的问题研究,深有感触,链接:http://blog.csdn.net/v_july_v/article/details/6685962
感谢July ^_^
他用的是Java的Hash Map等方法做了处理,讲解的非常深刻入骨
我也一时兴起,想拿Python试试刀,看看Python对于海量数据的处理能力如何。无奈在百度和Google输入“Python 海量数据”都无果。可能是国内使用python的不多,用python处理海量数据的就更少了。不过这浇灭不了我的欲望,哈哈
打算拿July的其中一个问题来试验一下:
海量日志数据,提取出某日访问百度次数最多的那个IP。
July给出的解决方案:
方案1:首先是这一天,并且是访问百度的日志中的IP取出来,逐个写入到一个大文件中。注意到IP是32位的,最多有2^32个IP。同样可以采用映射的方法,比如模1000,把整个大文件映射为1000个小文件,再找出每个小文中出现频率最大的IP(可以采用hash_map进行频率统计,然后再找出频率最大的几个)及相应的频率。然后再在这1000个最大的IP中,找出那个频率最大的IP,即为所求。
下手吧!
(一)生成数据
我首先构造1亿个IP,这些IP前两段都是“10.197”,后两段为0-255的随机数
把这1亿个IP存入一个文本文件中
Python代码如下:
__author__ = "Wally Yu (dayu.ebay@gmail.com)"
__date__ = "$Date: 2012/04/09 $"
def generateRandom(rangeFrom, rangeTo):
import random
return random.randint(rangeFrom,rangeTo)
def generageMassiveIPAddr(fileLocation,numberOfLines):
IP = []
file_handler = open(fileLocation, 'a+')
for i in range(numberOfLines):
IP.append('10.197.' + str(generateRandom(0,255))+'.'+ str(generateRandom(0,255)) + '\n')
file_handler.writelines(IP)
file_handler.close()
if __name__ == '__main__':
from time import ctime
print ctime()
for i in range(10):
print ' ' + str(i) + ": " + ctime()
generageMassiveIPAddr('d:\\massiveIP.txt', 10000000)
print ctime()
这里插一下,我的软件硬件环境:
硬件:
- ThinkPad T420(CPU: i7, 内存16G)
软件:
-OS: WinXP32位 (只认出3.6G内存)
- Python:2.7
从Python的print日志中基本可以看出,生成一千万条IP地址大概需要1分钟,生成1亿条记录需要10分钟
占据硬盘空间:1.4G
日志:
Mon Apr 09 16:52:28 2012
0: Mon Apr 09 16:52:28 2012
1: Mon Apr 09 16:53:28 2012
2: Mon Apr 09 16:54:29 2012
3: Mon Apr 09 16:55:30 2012
4: Mon Apr 09 16:56:32 2012
5: Mon Apr 09 16:57:33 2012
6: Mon Apr 09 16:58:36 2012
7: Mon Apr 09 16:59:36 2012
8: Mon Apr 09 17:00:36 2012
9: Mon Apr 09 17:01:35 2012
Mon Apr 09 17:02:36 2012
(二)处理思路
假设现在可用内存仅为128M,而每行IP经计算需要14Byte
因为数据太大,把1亿条数据载入内存,再做排序会导致内存溢出。July的思想:“以大化小,分而治之”非常合适,我转化后的操作思路:
1. 每行IP需要14B空间,那么128M内存最多可以处理 128M / 14B = 9142857个IP
把每36571429个IP拆成一个小文件保存起来,每个小文件的大小小于等于128M,共将生成11个文件
2. 对每个小文件用Hash Table处理,Python有自己非常高效的Hash Table:Dictionary!
具体处理如下:
1). 构建名为“Result”的Dictionary,“key”为IP地址,“value”为该IP地址出现的次数,用来记录11个文件每一个的最多出现的IP
2). 构建名为“IP”的Dictionary,“key”为IP地址,“value”为该IP地址出现的次数,用