Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/amazon-s3/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Amazon s3 使用boto3时如何提高AWS s3上传速度?_Amazon S3_Boto3 - Fatal编程技术网

Amazon s3 使用boto3时如何提高AWS s3上传速度?

Amazon s3 使用boto3时如何提高AWS s3上传速度?,amazon-s3,boto3,Amazon S3,Boto3,嘿,也有一些类似的问题,但没有一个完全像这样,而且相当多的问题已经过时多年了 我在服务器上编写了一些代码,通过boto3方法upload_文件使用密钥将jpeg照片上传到s3存储桶中。起初,这似乎很棒。这是一个将文件上传到s3的超级简单的解决方案 问题是,我有用户。我的用户正在通过手机应用程序向我的服务器发送他们的JPEG。虽然我承认我可以生成预先签名的上传URL并将它们发送到手机应用程序,但这需要对我们的手机应用程序和API进行大量重写 所以我只想让手机应用程序将照片发送到服务器。然后我想将照

嘿,也有一些类似的问题,但没有一个完全像这样,而且相当多的问题已经过时多年了

我在服务器上编写了一些代码,通过boto3方法upload_文件使用密钥将jpeg照片上传到s3存储桶中。起初,这似乎很棒。这是一个将文件上传到s3的超级简单的解决方案

问题是,我有用户。我的用户正在通过手机应用程序向我的服务器发送他们的JPEG。虽然我承认我可以生成预先签名的上传URL并将它们发送到手机应用程序,但这需要对我们的手机应用程序和API进行大量重写

所以我只想让手机应用程序将照片发送到服务器。然后我想将照片从服务器发送到s3。我实现了这个,但是它太慢了。我不能要求我的用户容忍这些缓慢的上传

我能做些什么来加快速度

我在谷歌上搜索了一下,发现:

这表明解决方案是增加TCP/IP连接的数量。更多的TCP/IP连接意味着更快的上传

好的,太好了

我该怎么做?如何增加TCP/IP连接的数量,以便更快地将单个jpeg上传到AWS s3


请帮忙。

讽刺的是,我们多年来一直在使用
bot3
,以及
awscli
,而且我们都喜欢它们

但是我们经常想知道为什么awscli的
aws s3 cp——递归的
,或者
aws s3同步的
,通常比通过
bot3
进行一系列上传要快得多,即使是
并发的.futures
线程池执行器
或者
进程池执行器
(你甚至不敢在你的员工中共享同一个
s3.Bucket
:有充分的理由警告他们不要进入,在最不方便的时候,严重的车祸最终会接踵而至)

最后,我咬紧牙关,查看了awscli在
bot3
之上引入的“定制”代码

基于这一小小的探索,这里有一种方法可以通过使用boto3.S3.transfer中已经内置的并发来加速许多文件到S3的上传,这不仅适用于单个大文件的多部分,也适用于各种大小的整组文件
boto3
文档中描述的
boto3
的高级API

以下是:

  • 使用
    boto3.s3.transfer
    创建一个
    TransferManager
    ,例如,与awscli的
    aws s3 sync
    使用的相同

  • 将最大线程数扩展到20

  • 增加底层
    urlib3
    botocore使用的最大池连接容量以匹配(默认情况下,它最多使用10个连接)

  • 为您提供了可选的回调功能(此处使用
    tqdm
    进度条演示,但您当然可以使用任何您想要的回调)

  • 速度很快(超过100MB/s——在ec2实例上测试)

  • 我举了一个完整的示例作为要点,其中包括生成500个随机csv文件,总容量约为360MB。但如果您假设下面的
    文件列表中有一堆文件,总容量为
    字节:

    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();
    
    导入操作系统
    进口boto3
    导入botocore
    导入boto3.s3.transfer作为s3transfer
    导入TQM
    botocore\u config=botocore.config.config(最大池连接数=20)
    s3client=boto3.client('s3',config=botocore\u config)
    transfer\u config=s3transfer.TransferConfig(
    使用_threads=True,
    最大并发度=20,
    )
    bucket_name=“”
    s3junkdir='some/path/for/junk'
    %%时间
    进度=tqdm.tqdm(
    desc='upload',
    总计=总尺寸,单位=B',单位刻度=1,
    位置=0,
    
    条形图格式{desc:您的应用程序是单线程的吗?如果是,那么限制是您一次只上载一个图像。您可以修改应用程序以同时发送更多图像。但是,显而易见的正确解决方案是让手机应用程序直接发送到Amazon S3。这使得它具有高度可扩展性,并降低了您的复杂性-终端服务器。谢谢!这大大提高了bucket操作的速度。希望我能不止一次投票给你!