广告
返回顶部
首页 > 资讯 > 后端开发 > Python >Python大数据量文本文件问题怎么解决
  • 458
分享到

Python大数据量文本文件问题怎么解决

2023-07-04 20:07:10 458人浏览 安东尼

Python 官方文档:入门教程 => 点击学习

摘要

这篇文章主要介绍“python大数据量文本文件问题怎么解决”,在日常操作中,相信很多人在Python大数据量文本文件问题怎么解决问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Python大数据量文本文件问题怎

这篇文章主要介绍“python大数据量文本文件问题怎么解决”,在日常操作中,相信很多人在Python大数据量文本文件问题怎么解决问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Python大数据量文本文件问题怎么解决”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

    测试环境

    Python 3.6.2

    Win 10 内存 8G,CPU I5 1.6 GHz

    背景描述

    这个作品来源于一个日志解析工具开发,这个开发过程中遇到的一个痛点,就是日志文件多,日志数据量大,解析耗时长。在这种情况下,寻思一种高效解析数据解析方案。

    解决方案描述

    1、采用多线程读取文件

    2、采用按块读取文件替代按行读取文件

    由于日志文件都是文本文件,需要读取其中每一行进行解析,所以一开始会很自然想到采用按行读取,后面发现合理配置下,按块读取,会比按行读取更高效。

    按块读取来的问题就是,可能导致完整的数据行分散在不同数据块中,那怎么解决这个问题呢?解答如下:

    将数据块按换行符\n切分得到日志行列表,列表第一个元素可能是一个完整的日志行,也可能是上一个数据块末尾日志行的组成部分,列表最后一个元素可能是不完整的日志行(即下一个数据块开头日志行的组成部分),也可能是空字符串(日志块中的日志行数据全部是完整的),根据这个规律,得出以下公式,通过该公式,可以得到一个新的数据块,对该数据块二次切分,可以得到数据完整的日志行

    上一个日志块首部日志行 +\n + 尾部日志行 + 下一个数据块首部日志行 + \n + 尾部日志行 + ...

    3、将数据解析操作拆分为可并行解析部分和不可并行解析部分

    数据解析往往涉及一些不可并行的操作,比如数据求和,最值统计等,如果不进行拆分,并行解析时势必需要添加互斥,避免数据覆盖,这样就会大大降低执行的效率,特别是不可并行操作占比较大的情况下。

    对数据解析操作进行拆分后,可并行解析操作部分不用加锁。考虑到Python GIL的问题,不可并行解析部分替换为单进程解析。

    4、采用多进程解析替代多线程解析

    采用多进程解析替代多线程解析,可以避开Python GIL全局解释锁带来的执行效率问题,从而提高解析效率。

    5、采用队列实现“协同”效果

    引入队列机制,实现一边读取日志,一边进行数据解析:

    • 日志读取线程将日志块存储到队列,解析进程从队列获取已读取日志块,执行可并行解析操作

    • 并行解析操作进程将解析后的结果存储到另一个队列,另一个解析进程从队列获取数据,执行不可并行解析操作。

    代码实现

    #!/usr/bin/env python# -*- coding:utf-8 -*-import reimport timefrom datetime import datetimefrom joblib import Parallel, delayed, parallel_backendfrom collections import dequefrom multiprocessing import cpu_countimport threadinGClass LogParser(object):    def __init__(self, chunk_size=1024*1024*10, process_num_for_log_parsing=cpu_count()):        self.log_unparsed_queue = deque() # 用于存储未解析日志        self.log_line_parsed_queue = deque()  # 用于存储已解析日志行        self.is_all_files_read = False  # 标识是否已读取所有日志文件        self.process_num_for_log_parsing = process_num_for_log_parsing # 并发解析日志文件进程数        self.chunk_size = chunk_size # 每次读取日志的日志块大小        self.files_read_list = [] # 存放已读取日志文件        self.log_parsing_finished = False # 标识是否完成日志解析    def read_in_chunks(self, filePath, chunk_size=1024*1024):        """        惰性函数(生成器),用于逐块读取文件。        默认区块大小:1M        """        with open(filePath, 'r', encoding='utf-8') as f:                        while True:                chunk_data = f.read(chunk_size)                if not chunk_data:                    break                yield chunk_data    def read_log_file(self, logfile_path):        '''        读取日志文件        这里假设日志文件都是文本文件,按块读取后,可按换行符进行二次切分,以便获取行日志        '''        temp_list = []  # 二次切分后,头,尾行日志可能是不完整的,所以需要将日志块头尾行日志相连接,进行拼接        for chunk in self.read_in_chunks(logfile_path, self.chunk_size):            log_chunk = chunk.split('\n')            temp_list.extend([log_chunk[0], '\n'])            temp_list.append(log_chunk[-1])            self.log_unparsed_queue.append(log_chunk[1:-1])        self.log_unparsed_queue.append(''.join(temp_list).split('\n'))        self.files_read_list.remove(logfile_path)    def start_processes_for_log_parsing(self):        '''启动日志解析进程'''        with parallel_backend("multiprocessing", n_jobs=self.process_num_for_log_parsing):            Parallel(require='sharedmem')(delayed(self.parse_logs)() for i in range(self.process_num_for_log_parsing))        self.log_parsing_finished = True    def parse_logs(self):        '''解析日志'''        method_url_re_pattern = re.compile('(HEAD|POST|GET)\s+([^\s]+?)\s+',re.DOTALL)        url_time_taken_extractor = re.compile('Http/1\.1.+\|(.+)\|\d+\|', re.DOTALL)        while self.log_unparsed_queue or self.files_read_list:            if not self.log_unparsed_queue:                continue            log_line_list = self.log_unparsed_queue.popleft()            for log_line in log_line_list:                #### do something with log_line                if not log_line.strip():                    continue                res = method_url_re_pattern.findall(log_line)                if not res:                    print('日志未匹配到请求URL,已忽略:\n%s' % log_line)                    continue                method = res[0][0]                url = res[0][1].split('?')[0]  # 去掉了 ?及后面的url参数                # 提取耗时                res = url_time_taken_extractor.findall(log_line)                if res:                    time_taken = float(res[0])                else:                    print('未从日志提取到请求耗时,已忽略日志:\n%s' % log_line)                    continue                # 存储解析后的日志信息                self.log_line_parsed_queue.append({'method': method,                                                   'url': url,                                                   'time_taken': time_taken,                                                   })    def collect_statistics(self):        '''收集统计数据'''        def _collect_statistics():            while self.log_line_parsed_queue or not self.log_parsing_finished:                if not self.log_line_parsed_queue:                    continue                log_info = self.log_line_parsed_queue.popleft()                # do something with log_info               with parallel_backend("multiprocessing", n_jobs=1):            Parallel()(delayed(_collect_statistics)() for i in range(1))    def run(self, file_path_list):        # 多线程读取日志文件        for file_path in file_path_list:            thread = threading.Thread(target=self.read_log_file,                                      name="read_log_file",                                      args=(file_path,))            thread.start()            self.files_read_list.append(file_path)        # 启动日志解析进程        thread = threading.Thread(target=self.start_processes_for_log_parsing, name="start_processes_for_log_parsing")        thread.start()        # 启动日志统计数据收集进程        thread = threading.Thread(target=self.collect_statistics, name="collect_statistics")        thread.start()        start = datetime.now()        while threading.active_count() > 1:            print('程序正在努力解析日志...')            time.sleep(0.5)        end = datetime.now()        print('解析完成', 'start', start, 'end', end, '耗时', end - start)if __name__ == "__main__":    log_parser = LogParser()    log_parser.run(['access.log', 'access2.log'])

    注意:

    需要合理的配置单次读取文件数据块的大小,不能过大,或者过小,否则都可能会导致数据读取速度变慢。笔者实践环境下,发现10M~15M每次是一个比较高效的配置。

    到此,关于“Python大数据量文本文件问题怎么解决”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注编程网网站,小编会继续努力为大家带来更多实用的文章!

    --结束END--

    本文标题: Python大数据量文本文件问题怎么解决

    本文链接: https://www.lsjlt.com/news/347199.html(转载时请注明来源链接)

    有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

    本篇文章演示代码以及资料文档资料下载

    下载Word文档到电脑,方便收藏和打印~

    下载Word文档
    猜你喜欢
    • Python大数据量文本文件问题怎么解决
      这篇文章主要介绍“Python大数据量文本文件问题怎么解决”,在日常操作中,相信很多人在Python大数据量文本文件问题怎么解决问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Python大数据量文本文件问题怎...
      99+
      2023-07-04
    • Python的文本文件转换编码问题怎么解决
      这篇文章主要介绍“Python的文本文件转换编码问题怎么解决”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Python的文本文件转换编码问题怎么解决”文章能帮助大家解决问题。测试数据注:测试文本采用...
      99+
      2023-07-06
    • 如何解决Mysql导入大容量SQL文件数据问题
      这篇文章主要介绍了如何解决Mysql导入大容量SQL文件数据问题,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。mysql在通过导入sql文件...
      99+
      2022-10-19
    • C#中获取文件大小问题怎么解决
      本篇内容主要讲解“C#中获取文件大小问题怎么解决”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“C#中获取文件大小问题怎么解决”吧!C# 获取文件大小直接贴代码吧   ...
      99+
      2023-07-05
    • SpringBoot上传文件大小受限问题怎么解决
      这篇文章主要介绍“SpringBoot上传文件大小受限问题怎么解决”,在日常操作中,相信很多人在SpringBoot上传文件大小受限问题怎么解决问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”SpringBoo...
      99+
      2023-06-30
    • 如何解决mysql导入数据库文件太大的问题
      这篇文章给大家分享的是有关如何解决mysql导入数据库文件太大的问题的内容。小编觉得挺实用的,因此分享给大家做个参考。一起跟随小编过来看看吧。mysql导入数据库的文件太大的解决办法:首先打开【php.in...
      99+
      2022-10-18
    • PDF拆分是怎么完美解决文件过大问题
      今天就跟大家聊聊有关PDF拆分是怎么完美解决文件过大问题,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。最近小编的一位朋友常常跟我吐槽:在工作的时候,要处理大量的PDF文档,有些文档非...
      99+
      2023-06-04
    • 怎么使用php解决大文件分片上传问题
      小编给大家分享一下怎么使用php解决大文件分片上传问题,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!前提首先, 上传超大的文件, 前端要和后端相互配合文件上传要使...
      99+
      2023-06-20
    • 怎么解决vue项目打包后文件过大问题
      这篇文章主要讲解了“怎么解决vue项目打包后文件过大问题”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“怎么解决vue项目打包后文件过大问题”吧!为什么打包后文件过大?移动app项目,使用vu...
      99+
      2023-06-30
    • python数据量太大怎么解决
      有几种方法可以解决Python处理大数据量的问题: 使用适当的数据结构:选择合适的数据结构来存储和处理大数据量,例如使用字典、集...
      99+
      2023-10-20
      Python
    • Python大数据量文本文件高效解析方案代码实现全过程
      目录测试环境背景描述解决方案描述代码实现总结测试环境 Python 3.6.2 Win 10 内存 8G,CPU I5 1.6 GHz 背景描述 这个作品来源于一个日志解析工具的开发...
      99+
      2022-12-19
      python文件数据分析 python处理大文本数据 python大数据量文本解析
    • 怎么解决php文件中文名乱码问题
      这篇文章主要介绍了怎么解决php文件中文名乱码问题,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。php文件中文名乱码的解决办法:1、在php文件的头部加入charset代码:...
      99+
      2023-06-22
    • 如何解决python 使用openpyxl读写大文件的问题
      这篇文章主要讲解了“如何解决python 使用openpyxl读写大文件的问题”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“如何解决python 使用openpyxl读写大文件的问题”吧!由...
      99+
      2023-06-14
    • web前端大文件上传与下载问题怎么解决
      这篇文章主要介绍了web前端大文件上传与下载问题怎么解决的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇web前端大文件上传与下载问题怎么解决文章都会有所收获,下面我们一起来看看吧。一、问题日常业务中难免出现前端...
      99+
      2023-07-04
    • 怎么解决php不能上传中文文件问题
      这篇文章主要介绍“怎么解决php不能上传中文文件问题”,在日常操作中,相信很多人在怎么解决php不能上传中文文件问题问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”怎么解决php不能上传中文文件问题”的疑惑有所...
      99+
      2023-06-20
    • win10日志文件c:Windowssystem32logfiles问题怎么解决
      今天小编给大家分享一下win10日志文件c:Windowssystem32logfiles问题怎么解决的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下...
      99+
      2023-07-01
    • windows dll文件常见问题怎么解决
      这篇文章主要讲解了“windows dll文件常见问题怎么解决”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“windows dll文件常见问题怎么解决”吧!dll文件修复使用方法一、wtux...
      99+
      2023-07-01
    • 怎么解决MySQL参数文件没有生效问题
      本篇内容介绍了“怎么解决MySQL参数文件没有生效问题”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成! ...
      99+
      2022-10-19
    • 如何解决MySQL导入数据库文件最大限制2048KB的问题
      这篇文章将为大家详细讲解有关如何解决MySQL导入数据库文件最大限制2048KB的问题,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。引子:今天为进行服务器空间的转移~~~...
      99+
      2022-10-19
    • Flume采集数据时在HDFS上产生大量小文件的问题怎么办
      这篇文章主要为大家展示了“Flume采集数据时在HDFS上产生大量小文件的问题怎么办”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“Flume采集数据时在HDFS上产生大量小文件的问题怎么办”这篇...
      99+
      2023-06-02
    软考高级职称资格查询
    编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
    • 官方手机版

    • 微信公众号

    • 商务合作