使用boto3在同一个S3存储桶内移动对象的最快方法
S3同存储桶前缀文件快速复制优化方案
性能问题原因
你目前的实现是串行同步执行,每次copy请求都需要等待前一次请求的网络往返完全结束才会发起下一次,小文件场景下绝大部分耗时都消耗在网络等待上,而非实际文件操作。
优化方案
方案1:线程池并发执行(最适合当前小文件场景)
IO密集型场景下用多线程并发发起copy请求,能大幅压缩总耗时,200个小文件通常可以压缩到2秒以内完成。
示例代码如下:
import os from concurrent.futures import ThreadPoolExecutor, as_completed # 配置参数 my_bucket = "你的桶名" source_prefix = "源前缀/" target_prefix = "目标前缀/" # 可根据实际网络情况调整,S3单前缀默认支持每秒3500次PUT请求,小文件场景可以开到50-100 max_workers = 50 # 拉取源前缀下所有文件(也可以用你自己已有的file_list生成逻辑) file_list = [] paginator = s3_client.get_paginator('list_objects_v2') for page in paginator.paginate(Bucket=my_bucket, Prefix=source_prefix): if 'Contents' in page: file_list.extend([obj['Key'] for obj in page['Contents']]) # 单文件复制逻辑 def copy_file(source_key): # 拼接目标Key,避免所有文件被覆盖成同一个名称 filename = os.path.basename(source_key) target_key = f"{target_prefix}{filename}" copy_source = {'Bucket': my_bucket, 'Key': source_key} s3_client.copy(copy_source, my_bucket, target_key) return source_key # 并发执行 with ThreadPoolExecutor(max_workers=max_workers) as executor: futures = [executor.submit(copy_file, key) for key in file_list] for future in as_completed(futures): # 可选:在这里添加完成日志、异常处理逻辑 pass
方案2:S3 Batch Operations(适合十万级以上文件批量操作)
如果需要操作的文件量级超过10万,可以直接使用S3原生的批量操作功能,不需要自己写并发逻辑,S3后台会自动调度执行。
额外注意
你原来的代码中s3_client.copy的第三个参数直接传了new_prefix,如果不拼接文件名的话会导致所有源文件都被覆盖为同一个目标文件,这个问题需要先修正。
内容的提问来源于stack exchange,提问作者smallbirds
相关产品推荐
相关产品推荐

