aws s3 预签名 方式 分块上传

https://github.com/aws/aws-sdk-java/issues/1537

https://stackoverflow.com/questions/61682171/problem-in-uploading-multipart-amazon-s3-rest-api-using-postman/63965057

base64  hex编码工具:
https://emn178.github.io/online-tools/base64_encode.html

使用预签名 URL 对大文件进行分段上传 - AW

数据增长的速度之快令人震惊。现在可以以每秒超过一百万个请求的频率收集原始数据。存储更快更便宜。几乎永远存储数据是正常的,即使它很少被访问。

Traindex的用户可以上传大数据文件来创建语义搜索索引。本文将解释我们如何实现允许 Traindex 用户上传大文件的分段上传功能。

问题及其解决方案

我们希望 Traindex 的用户能够在最短的时间内通过适当的访问控制将大文件(通常为 1-2 TB)上传到 Amazon S3。

在本文中,我将讨论如何设置预签名 URL 以安全上传文件。这允许我们在不需要许可的情况下授予对 AWS S3 存储桶中对象的临时访问权限。

那么在上传到 AWS S3 时如何从 5GB 限制变为 5TB 限制?使用分段上传,AWS S3 允许用户上传分区为 10,000 个部分的文件。每个部分的大小可能从 5MB 到 5GB 不等。

下表显示了 S3 的上传服务限制。

在这里插入图片描述

除了大小限制之外,最好将 S3 存储桶保持私有,并仅在需要时授予公共访问权限。我们希望在不更改存储桶 ACL、创建角色或在我们的账户上创建用户的情况下授予客户端访问对象的权限。我们最终使用了 S3 预签名 URL。

你会学到什么?

为了使标准分段上传能够与预签名 URL 一起使用,我们需要:

  1. 启动分段上传
  2. 为每个部分创建预签名 URL
  3. 上传对象的部分
  4. 完成分段上传

先决条件

您必须确保已将命令行环境配置为在操作时不需要凭据。上述步骤 1、2 和 4 是服务器端阶段。他们将需要 AWS 访问密钥 ID 和密钥 ID。第 3 步是一个客户端操作,正在为其设置预签名 URL,因此不需要凭据。

如果您尚未将环境配置为执行服务器端操作,则必须先按照以下步骤完成它:

$ aws configure

AWS Access Key ID [None]: EXAMPLEFODNN7EXAMPLE
AWS Secret Access Key [None]: eXaMPlEtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
Default region name [None]: xx-xxxx-x
Default output format [None]: json

执行

1. 启动分段上传

在这个阶段,我们请求 AWS S3 启动分段上传。作为响应,我们将获得UploadId,它将每个部分与他们正在创建的对象相关联。

import boto3

s3 = boto3.client('s3')

bucket = "[XYZ]"
key = "[ABC.pqr]"

response = s3.create_multipart_upload(
    Bucket=bucket, 
    Key=key
)

upload_id = response['UploadId']

在设置了存储桶名称和密钥之后执行这段代码,我们得到了我们要上传的文件的 UploadID。设置完bucket名称和key后,我们就得到了需要上传的文件的UploadID。稍后将需要组合所有部分。

2. 为每个部分创建预签名 URL

现在可以通过 PUT 请求上传这些部分。如前所述,我们使用预签名 URL 来提供一种安全的方式来上传和授予对对象的访问权限,而无需更改存储桶 ACL、创建角色或在您的账户上提供用户。允许的用户可以为文件的每个部分生成 URL 并访问 S3。以下代码行可以生成它:

signed_url = s3.generate_presigned_url(
    ClientMethod ='upload_part',
    Params = {
       'Bucket': bucket,
       'Key': key, 
       'UploadId': upload_id, 
       'PartNumber': part_no
    }
)

如上所述,此特定步骤是服务器端阶段,因此需要预配置的 AWS 环境。现在可以将每个部分的预签名 URL 移交给客户端。他们可以简单地上传各个部分,而无需直接访问 S3。这意味着服务提供者不再需要担心 ACL 和权限的变化。

3.上传对象的部分

此步骤是该过程的唯一客户端阶段。默认的预签名 URL 过期时间为 15 分钟,而生成它的人可以更改该值。通常,出于安全原因,它会尽可能地保持最小。

客户端可以读取对象的部分,即file_data,并请求上传与部分号相关的数据块。必须按顺序使用预签名的 URL 作为部件号,并且数据块必须按顺序排列;否则,对象可能会损坏,并且上传以损坏的文件结束。出于这个原因,必须管理字典,即parts来存储唯一标识符,即与零件号有关的每个零件的**eTag 。**字典必须是管理器,以保存数字的每个部分的唯一标识符或 eTag。

response = requests.put(signed_url, data=file_data)

etag = response.headers['ETag']  

parts.append({'ETag': etag, 'PartNumber': part_no})

就数据的大小而言,可以将每个块声明为字节或通过将对象的总大小除以编号来计算。的零件。看下面的示例代码:

max_size = 5 * 1024 * 1024    # Approach 1: Assign the size 
max_size = object_size/no_of_parts    # Approach 2: Calculate the size 
with open(fileLocation) as f:
    file_data = f.read(max_size)
4.完成分段上传

在此步骤之前,请检查数据的块和上传到存储桶的详细信息。现在,我们需要将所有部分文件合并为一个。字典部分(我们在步骤 3 中讨论过的部分)将作为参数传递,以保留块及其部件号和 eTag,以避免对象损坏。

您可以参考下面的代码来完成分段上传过程。

response = s3.complete_multipart_upload(
    Bucket = bucket,
    Key = key,
    MultipartUpload = {'Parts': parts},
    UploadId= upload_id
)
5. 附加步骤

为避免任何额外费用和清理,您的 S3 存储桶和 S3 模块会根据请求停止分段上传。如果任何事情看起来可疑并且想要中止该过程,他们可以使用以下代码:

response = s3.abort_multipart_upload(
    Bucket = bucket,
    Key = key,
    UploadId = upload_id
)

在本文中,我们讨论了以安全方式预签名 URL 实现分段上传过程的过程。建议的解决方案是制作一个CLI 工具来上传大文件,这可以节省时间和资源,并为用户提供灵活性。对于需要经常这样做的用户来说,这是一种廉价而高效的解决方案。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值