嘿,有一些类似的问题,但没有一个完全像这样,而且相当多的问题已经存在多年并且已经过时了。
我在我的服务器上编写了一些代码,通过 boto3 方法 upload_file 使用密钥将 jpeg 照片上传到 s3 存储桶。最初这看起来很棒。这是一个将文件上传到 s3 的超级简单的解决方案。
问题是,我有用户。我的用户通过电话应用程序将他们的 jpeg 发送到我的服务器。虽然我承认我可以生成预先签名的上传 URL 并将它们发送到电话应用程序,但这需要对我们的电话应用程序和 API 进行大量重写。
所以我只希望手机应用程序将照片发送到服务器。然后我想将照片从服务器发送到 s3。我实现了这个,但它太慢了。我不能要求我的用户容忍这些缓慢的上传。
我能做些什么来加快速度?
我做了一些谷歌搜索,发现这个:https : //medium.com/@alejandro.millan.frias/optimizing-transfer-throughput-of-small-files-to-amazon-s3-or-anywhere-really-301dca4472a5
它建议解决方案是增加 TCP/IP 连接数。更多的 TCP/IP 连接意味着更快的上传。
好的,太好了!
我怎么做?如何增加 TCP/IP 连接数,以便更快地将单个 jpeg 上传到 AWS s3?
请帮忙。
具有讽刺意味的是,我们已经使用boto3了多年awscli,并且我们都喜欢它们。
但是我们经常想知道为什么 awscli 的aws s3 cp --recursive, or aws s3 sync,通常比尝试通过 进行一堆上传要快得多boto3,即使使用concurrent.futures's ThreadPoolExecutoror ProcessPoolExecutor(并且您甚至不敢s3.Bucket在您的工作人员之间共享相同的内容:在文档,并且有充分的理由;令人讨厌的崩溃最终会在最不方便的时候发生)。
最后,我硬着头皮查看了 awscli 在boto3.
基于这个小小的探索,这里有一种方法可以通过使用内置的并发来加速将许多文件上传到 S3 boto3.s3.transfer,不仅适用于单个大文件的可能多部分,还适用于各种不同的文件。尺寸也是如此。据我所知,该功能并未通过文档boto3中描述的更高级别的 API 公开boto3。
下列:
例如,用于boto3.s3.transfer创建一个TransferManager,与 awscli 使用的完全相同aws s3 sync。
将最大线程数扩展到 20。
增加urllib3用于botocore匹配的底层最大池连接容量(默认情况下,它最多使用 10 个连接)。
为您提供可选的回调功能(此处使用tqdm进度条进行演示,但当然您可以使用任何您想要的回调)。
是快速(超过100MB / s的--tested上的EC2实例)。
我在这里放了一个完整的例子作为要点,其中包括生成 500 个随机 csv 文件,总共约 360MB。但是如果你假设你在filelist下面有一堆文件,总共total_size字节:
import os
import boto3
import botocore
import boto3.s3.transfer as s3transfer
import tqdm
botocore_config = botocore.config.Config(max_pool_connections=20)
s3client = boto3.client('s3', config=botocore_config)
transfer_config = s3transfer.TransferConfig(
use_threads=True,
max_concurrency=20,
)
bucket_name = '<your-bucket-name>'
s3junkdir = 'some/path/for/junk'
%%time
progress = tqdm.tqdm(
desc='upload',
total=total_size, unit='B', unit_scale=1,
position=0,
bar_format='{desc:<10}{percentage:3.0f}%|{bar:10}{r_bar}')
s3t = s3transfer.create_transfer_manager(s3client, transfer_config)
for src in filelist:
dst = os.path.join(s3junkdir, os.path.basename(src))
s3t.upload(
src, bucket_name, dst,
subscribers=[
s3transfer.ProgressCallbackInvoker(progress.update),
],
)
s3t.shutdown() # wait for all the upload tasks to finish
progress.close();
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2288 次 |
| 最近记录: |