Python 处理大量大型文件

Python 处理大量大型文件,下面是一个多进程应用程序的示例。我们将从Web日志文件中提取通用日志格式(common log format,CLF),这是Web服务器的访问日志较常用的一种格式。文件中的行往往很长,但因书的页边距换行后会如下所示:

99.49.32.197 - - [01/Jun/2012:22:17:54 -0400] "GET /favicon.ico
 HTTP/1.1" 200 894 "-" "Mozilla/5.0 (Windows NT 6.0)
 AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.52
 Safari/536.5"

通常需要分析大量文件。许多独立文件的存在意味着并发有助于信息抓取。
分析过程可分解为两个比较宽泛的功能。处理的第一阶段是对日志文件进行必要的解析,以收集相关信息片段。我们把该解析过程细分为4个阶段,如下所示:
(1) 读取多个源日志文件的所有行数据;
(2) 然后为文件集合中每一行日志条目创建简单的命名元组对象;
(3) 解析日期和URL等复杂字段的详细信息;
(4) 从日志中排除不感兴趣的路径名,也可以将其看作只解析感兴趣的路径名。
解析阶段过后便可以执行大量分析操作了。下面通过一个用于计算特定路径出现频次的简单分析来演示multiprocessing模块。

第一部分是读取包含大部分输入处理的源文件。Python利用文件迭代器把对缓冲数据的请求转化为了底层操作系统的请求。操作系统的每个请求都意味着进程必须等待直到数据可用。

显然,如果同时交错其他操作,它们就无须等待I/O完成了。交错执行的数据范围可以从独立的行数据到整个文件数据。首先考虑交错执行整个文件,因为这相对容易实现。

解析Apache CLF文件的函数式设计如下所示:

data = path_filter(
    access_detail_iter(
        access_iter(
            local_gzip(filename))))

较大的解析问题分解为了许多函数,由这些函数负责处理解析问题的每个部分。函数lcoal_gzip()从本地缓存的GZIP文件中读取行数据。函数access_iter()在访问日志中为每一行创建了一个NamedTuple对象。函数access_detail_iter()扩展到一些更难解析的字段。最后,函数path_filter()将丢弃一些分析价值不大的路径和文件扩展名。
如下所示的管道处理有助于将这种设计可视化:

(local_gzip(filename) | access_iter | access_detail_iter | path_filter) > data

这里使用了shell的管道符号(|)将数据从一个进程传递至另一个进程。Python内置的pipes模块支持构建实际的shell管道来利用操作系统的多进程能力。其他包(如pipetoolspipe)提供了类似的可视化复合函数的方法。

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程