Python 使用concurrent.futures和ThreadPool上载200万个文件(从EC2到S3的每个文件约30 KB),这需要花费大量时间
我们需要上传大约200万个文件(从EC2实例到S3的每个文件大约30KB)。我们正在使用python、boto3和concurrent.futures模块来实现这一点。下面是伪代码Python 使用concurrent.futures和ThreadPool上载200万个文件(从EC2到S3的每个文件约30 KB),这需要花费大量时间,python,amazon-s3,python-multithreading,concurrent.futures,Python,Amazon S3,Python Multithreading,Concurrent.futures,我们需要上传大约200万个文件(从EC2实例到S3的每个文件大约30KB)。我们正在使用python、boto3和concurrent.futures模块来实现这一点。下面是伪代码 import concurrent.futures from concurrent.futures import ThreadPoolExecutor class UploadToS3: def upload(self, file_path): try: s3 =
import concurrent.futures
from concurrent.futures import ThreadPoolExecutor
class UploadToS3:
def upload(self, file_path):
try:
s3 = boto3.resource('s3')
bucket = s3.Bucket('xxxxxxxxxx')
destination_file_path = 'yyyyy'
bucket.upload_file(file_path,destination_file_path)
del s3
except (Exception) as e :
print(e)
def upload_files(self, file_paths):
with concurrent.futures.ThreadPoolExecutor(max_workers=2000) as executor:
tracker_futures = []
for file_path in file_paths:
tracker_futures.append(executor.submit(self.upload,file_path))
for future in concurrent.futures.as_completed(tracker_futures):
tracker_futures.remove(future)
del future
然而,我们发现,我们每小时只能上传约78000个文件,增加线程数量没有多大效果,我们相信这是因为GIL,当我们尝试使用ProcessPoolExecutor时,我们遇到了问题,因为boto3对象不可拾取。任何关于如何克服这种情况的建议根据我的一般经验,这听起来相当不错-每秒约21个文件 可能更有效的方法是:
- 将200万个文件压缩成一个巨大的归档文件
- 将该归档文件上载到与S3 bucket位于同一AWS数据中心的EC2实例
- 解压缩EC2实例上的文件
- 在EC2实例上运行Python脚本
虽然S3似乎比许多其他系统做得更好,但您可能还想考虑,如果您还没有这样做,设置S3文件夹,以便200万个文件不在(相当于)一个目录中。但是,根据文件的命名方案和文件的最终用途,这可能很容易做到,也可能不容易做到。上传200万个文件将花费大量时间,无论您如何操作。我们正是这样做的。我们将文件作为一个巨大的zip文件接收,解压后上传到S3。来自同一区域中的EC2实例。然而,所有的文件都在一个键下,你建议每个对象的不同键是什么?对我来说,“本地机器”意味着“我的物理桌面/笔记本电脑/服务器”,而不是“AWS内部的EC2”-所以听起来你已经解决了这一部分。我会用一个键来表示一切(没有真正的选择)和一个bucket(因为每个客户的bucket数量有限),但在bucket中设置文件夹,使每个bucket都有数千个而不是数百万个文件。从技术上讲,文件不在文件夹中,但基本上如果在名称的各个部分之间使用分隔符,S3基本上将名称视为典型*nix操作系统中的/folder/subfolder/subsubfolder/etc/filename。