Python 实现大文件的高并发下载

news2025/3/18 13:28:40

项目背景

基于一个 scrapy-redis 搭建的分布式系统,所有item都通过重写 pipeline 存储到 redislist 中。这里我通过代码演示如何基于线程池 + 协程实现对 item 的中文件下载。

  • Item 结构

    目的是为了下载 item 中 attachments 保存的附件内容。

    {
        "crawl_time":
        "20221017 12:00:00",
        "version":
        "20221017 12:00:00",
        "data": [{
            "title": "",
            "attachments": [
                {
                    "ori_url": "https://www.baidu.com",	# 文件地址
                    "path": "",	# 文件本地保存路径
                    "filename": "xxx"	# 文件名称
                }
            ]
        }]
    }
    

一、批量获取 item

为了能够提高数据的存储效率,选择从 redis 中弹出多个 item,但当前部署的 redis 版本为 5.0lpop 不支持同时弹出多个数据,需要通过 LRANGELTRIM 命令实现,但是两个命令执行不是原子操作,在多线程的情况下会导致数据异常,因此通过 lua 脚本执行批量弹出多个 item

1.1 lua 脚本

在这里插入图片描述

1.2 读取数据

设定好批量读取的大小,执行 lua 脚本,获取数据。
在这里插入图片描述

二、并发

2.1 线程池

使用线程池去管理这么多 item 下载任务的原因:

  • 减少频繁创建和销毁线程的开销
  • 控制并发数量,防止不断创建线程导致资源耗尽
  • 复用线程,减少线程切换开销

将获取到的 data 进行分片,分片后的数据交给多个线程去下载,提高并发效率。
在这里插入图片描述

2.2 协程任务

每个线程新建一个事件循环对象 loop,用来管理分片后的 data 协程任务。

为了复用 TCP 连接和 session,选择让分片 data 共享一个 TCPConnectorClientSession 对象。这是基于 data 分片大小大概率是同一个网站的数据设计的,可以降低连接创建会话管理的的资源消耗。
在这里插入图片描述

2.3 协程并发

通过 asyncio.gather 实现协程并发。
在这里插入图片描述

三、大文件分块

下载文件时,如果文件比较大,网络又不稳定的情况下,很容易导致下载失败,因此这里通过将文件分块下载优化流程。

3.1 分块

对文件分块之前,先要获取文件大小。向服务器发送一个预请求 head,来获取文件长度,这样可以避免获取整个文件,减少网络传输耗时。
在这里插入图片描述
然后对文件进行分块处理,在传输中,需要平衡 网络拥塞请求频次 导致的消耗,这里选择将文件分为 1024 * 1024 也就是 1 MB 的块大小。

使用 asyncio.Semaphore 控制 同时进行的下载任务数量,避免过多并发导致服务器崩溃。
在这里插入图片描述

3.2 下载

修改 headers 中的 Range 获取文件指定块大小的内容。

通过装饰器实现文件的断点续传功能,防止因网络不稳定导致文件内容缺失。
在这里插入图片描述
当文件的某个块下载失败,超出重试次数时,取消所有该文件块的下载任务,暂时放弃该文件,记录到失败下载队列中保存,避免因为问件本就损坏这种情况导致不断重试。
在这里插入图片描述
异步装饰器的实现
在这里插入图片描述

3.3 拼接

result 按顺序返回请求的结果,将请求的文件块拼接完成。
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2317246.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【最新】 ubuntu24安装 1panel 保姆级教程

系统:ubuntu24.04.1 安装软件 :1panel 第一步:更新系统 sudo apt update sudo apt upgrade 如下图 第二步:安装1panel,运行如下命令 curl -sSL https://resource.fit2cloud.com/1panel/package/quick_start.sh -o …

c++图论(二)之图的存储图解

在 C 中实现图的存储时,常用的方法包括 邻接矩阵(Adjacency Matrix)、邻接表(Adjacency List) 和 边列表(Edge List)。以下是具体实现方法、优缺点分析及代码示例: 1. 邻接矩阵&…

c++图论(一)之图论的起源和图的概念

C 图论之图论的起源和图的概念 图论(Graph Theory)是数学和计算机科学中的一个重要分支,其起源可以追溯到 18 世纪 的经典问题。以下是图论的历史背景、核心起源问题及其与基本概念和用途: 借用一下CSDN的图片哈 一、图论的起源&…

ChatGPT and Claude国内使用站点

RawChat kelaode chatgptplus chatopens(4.o mini免费,plus收费) 网页: 定价: wildcard 网页: 虚拟卡定价: 2233.ai 网页: 定价: MaynorAPI chatgpt cla…

进行性核上性麻痹:精心护理,点亮希望之光

进行性核上性麻痹是一种罕见的神经退行性疾病,严重影响患者的生活质量。有效的健康护理能够在一定程度上缓解症状、延缓病情发展,给患者带来更好的生活体验。 在日常生活护理方面,由于患者平衡能力逐渐下降,行动不便,居…

ZED X系列双目3D相机的耐用性与创新设计解析

在工业自动化和学术研究领域,高精度的视觉设备正成为提升效率和质量的关键。ZED X系列AI立体相机,凭借其先进的技术和耐用的设计,为这一领域带来了新的可能。 核心技术:深度感知与精准追踪 ZED X系列的核心技术之一是Neural Dept…

HarmonyOS三层架构实战

目录: 1、三层架构项目结构1.0、三层架构简介1.1、 common层(主要放一些公共的资源等)1.2、 features层(主要模块定义的组件以及图片等静态资源)1.3、 products层(主要放主页面层和一些主要的资源&#xff…

计算机四级 - 数据库原理 - 第4章 「关系数据库标准语言SQL」

4.1 SQL概述 4.1.1 结构化查询语言SQL SQL(Structured Query Language)称为结构化查询语言,它是由1974年由Boyce和Chamberi提出的,1975年至1979年IBM公司的San Jose Research Laboratory研制了关系数据库管理系统的原型系统System R,并实现了这种语198…

基于PMU的14节点、30节点电力系统状态估计MATLAB程序

“电气仔推送”获得资料(专享优惠) 程序简介: 程序采用三种方法对14节点和30节点电力系统状态进行评估: ①PMU同步向量测量单元结合加权最小二乘法(WLS)分析电力系统的电压幅值和相角状态; …

Deepseek API+Python测试用例一键生成与导出-V1.0.2【实现需求文档图片识别与用例生成自动化】

在测试工作中,需求文档中的图片(如界面设计图、流程图)往往是测试用例生成的重要参考。然而,手动提取图片并识别内容不仅耗时,还容易出错。本文将通过一个自研小工具,结合 PaddleOCR 和大模型,自…

整形在内存中的存储(例题逐个解析)

目录 一.相关知识点 1.截断: 2.整形提升: 3.如何 截断,整型提升? (1)负数 (2)正数 (3)无符号整型,高位补0 注意:提升后得到的…

蓝牙系统的核心组成解析

一、硬件层:看得见的物理载体 1. 射频模块(Radio Frequency Module) 专业描述:工作在2.4GHz ISM频段,支持GFSK/π/4 DQPSK/8DPSK调制方式 功能类比:相当于人的"嘴巴"和"耳朵" 发射端…

uniapp笔记-底部和首部标签页菜单生成

逻辑 这些都是需要配置pages.json文件。 其中底部需要手动配置tarBar,如: "tabBar": {"list":[{"pagePath": "pages/index/index","text": "首页"},{"pagePath": "pages/…

SpringBoot 和vue前后端配合开发网页拼图10关游戏源码技术分享

今天分享一个 前后端结合 的网页游戏 开发项目源码技术。 这也是我第一次写游戏类的程序,虽然不是特别复杂的游戏,但是是第一次写,肯定要记录一下了,哈哈。 游戏的内容 就是 我们显示中玩的那个 拼图碎片的 游戏,类似下…

OpenCV计算摄影学(21)非真实感渲染之边缘保留滤波器edgePreservingFilter()

操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 滤波是图像和视频处理中的基础操作。边缘保留平滑滤波器被广泛应用于多种不同场景[98]。 cv::edgePreservingFilter 是一种边缘保留滤波器&#…

JVM并发编程AQSsync锁ReentrantLock线程池ThreadLocal

并发编程2 synchronized锁实现**AQS****ReentrantLock实现****JUC 常用类**池的概念 ThreadLocalThreadLocal原理内存泄露强引用:软引用弱引用虚引用ThreadLocal内存泄露 synchronized锁实现 synchronized是一个关键字,实现同步,还需要我们提供一个同步锁对象,记录锁状态,记录…

什么是数学建模?数学建模是将实际问题转化为数学问题

数学建模是将实际问题转化为数学问题,并通过数学工具进行分析、求解和验证的过程。 一、数学建模的基本流程 问题分析 • 明确目标:确定需要解决的核心问题。 • 简化现实:识别关键变量、忽略次要因素。 • 定义输入和输出:明确模…

唤起“队列”的回忆

又来博客记录自己的学习心得了,嘿嘿嘿(^~^) 目录 队列的概念和结构: 队列的创建和初始化: 队列入栈: 队列出栈: 队列的销毁: 取队头和队尾数据: 结语: 队列的概念…

Linux(8.4)NFS

文章目录 一、概念二、详解NFS1)软件名2)服务名3)配置文件4)端口号5)相关命令 三、部署NFS一、NFS服务端1)**配置源(本地或者网络源)**2)2、安装NFS**3)启动服…

【位运算】速算密钥:位运算探秘

文章目录 前言例题一、判定字符是否唯一二、丢失的数字三、两整数之和四、只出现⼀次的数字 II五、消失的两个数字 结语 前言 什么是位运算算法呢? 位运算算法是以位运算为核心操作,设计用来高效解决特定问题的一系列计算步骤集合。它巧妙利用位运算直接…