You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Python多进程下载S3文件时出现HeadObject 404错误如何解决?

报错原因
  • boto3的S3 Resource/Client实例不支持跨进程序列化传递,也不是进程安全的。你在父进程初始化的s3_resource通过multiprocessing.Process的args参数传递给子进程时,会经过pickle序列化、子进程反序列化的流程,这个过程会破坏实例底层持有的HTTP连接池、签名凭证缓存、请求上下文等内部状态。
  • S3为了避免未授权用户判断资源是否存在,签名异常、请求路径解析错误等非资源不存在的场景也可能返回404状态码,这也是你明明确认资源存在、权限正常却收到404的直接原因。你遇到的单个文件下载成功只是巧合,是某一个子进程反序列化后的实例刚好还保留了可用的状态。
解决方案

方案1:子进程内部单独初始化S3 Resource(推荐多进程场景使用)

不要在父进程创建S3实例后传递给子进程,改为每个子进程执行下载逻辑前单独初始化自己的S3实例:

import multiprocessing as mp
import boto3

def download_parallel(bucket, prefix):
    # 子进程内部单独初始化S3资源
    s3_resource = boto3.resource('s3')
    # path = compute where to download using prefix
    s3_resource.Object(bucket, prefix).download_file(path)

p_list = []
for prefix in prefixes:
    # 不再传递s3_resource参数
    p = mp.Process(target=download_parallel, args=(bucket, prefix))
    p.start()
    p_list.append(p)

for p in p_list:
    p.join()

方案2:改用多线程实现并行下载(推荐IO密集型场景使用)

S3下载属于IO密集型任务,多线程的开销远低于多进程,且boto3的S3实例是线程安全的,可以直接在多个线程中复用同一个实例:

from concurrent.futures import ThreadPoolExecutor
import boto3

s3_resource = boto3.resource('s3') # 可以全局初始化复用

def download_parallel(bucket, prefix):
    # path = compute where to download using prefix
    s3_resource.Object(bucket, prefix).download_file(path)

# 按需调整线程数,通常设置为10-30即可满足S3下载的带宽需求
with ThreadPoolExecutor(max_workers=10) as executor:
    for prefix in prefixes:
        executor.submit(download_parallel, bucket, prefix)

内容的提问来源于stack exchange,提问作者Rishabh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 17:36:03