【问题标题】:Move large file (500GB or more) between s3 buckets without a Server在没有服务器的 s3 存储桶之间移动大文件(500GB 或更多)
【发布时间】:2020-05-22 06:43:04
【问题描述】:

我有一个小的 Python 脚本,它运行 Lambda 作业,以便在上传文件后立即将文件从不受限制的 s3 存储桶移动到受限制的 s3 存储桶。最初的目标是 50GB 文件,现在是 500GB 文件(或更大)的目标。 Lambda 容器在 15 分钟停止,我只能在 Lambda 超时结束前传输大约 100GB。

s3_resource = boto3.resource('s3')  #for s3 delete function
... other stuff ...
s3_resource.meta.client.copy(Bucket=target_bucket, Key=key, CopySource=copy_source, ExtraArgs={'ServerSideEncryption':'AES256'})
#boto3 manual states s3_resource.meta.client.copy "is a managed transfer which will perform a multipart copy in multiple threads if necessary."

我环顾四周,发现的选项是:

  1. 使用 ECS 容器运行作业,由 s3 事件和 lambda 触发
  2. 使用 Step Functions 为分段上传生成一个循环,持续时间超过 15 分钟

我还没有使用过以太服务。 ECS 与 Step Function 的优缺点是什么?他们是否可以调整其他方式(代码或设置)以提高文件传输限制。

更新 1 系统详情。

“公共”存储桶用于 SFTP 服务。这是替换 Linux 机器上的 SFTP 服务器。 当文件发送给我时,Lambda 会检查内部需要放置的位置。 当我使文件可供下载时,该文件所在目录的 lambda 会将其放置在正确的 SFTP 目录中。在给定窗口之后存储桶策略存档文件,除非再次需要,否则不允许下载它们。 目标是发送给我的文件不会保留在公开/SFTP 公开的存储桶上。当文件发布以供下载时,它们只会在一段时间内存在。而我的内部存储桶保留和使用文件。 即使有 SFTP 访问控制层,我也希望外部暴露的存储桶大部分是空的。

更新 1 找到 Step Function 分段上传示例

我发现了一个示例,其中包含一些分段上传的代码片段(顺序 [a, 然后 b, 然后 c...] 和并行部分 [a, b, and c, 然后...] )。它看起来确实像很多会话 ID 管理。不同的是,在很长时间没有看它之后,我不想在 6 个月内遇到麻烦。

【问题讨论】:

  • 你可以选择使用 scp 吗?
  • @Danizavtz scp = 安全复制 linux 命令?我正在尝试无服务器。当我的机器在 15 分钟后没有超时时,我可以很好地移动这些大文件。 scp = aws 安全控制策略?如果您的想法是通过解决对象权限来避免移动,则移动作业具有一些有助于在上传后组织文件的逻辑。
  • 我的意思是linux命令。
  • 我在考虑简单的解决方案,也许在复制之前做一些 tar.gz。如果文件大小变为 100GB 左右,也许您无需对代码进行大的更改即可完成这项工作。
  • S3 复制是这里最好的解决方案,如果你可以使用它的话。您甚至不再需要您的 Lambda 函数。关于 scp 的建议对于 S3 毫无意义。如果您必须自己构建它,我会在 Fargate 上使用 S3 通知 -> SQS 队列 -> ECS 任务,该任务会根据队列的深度自动缩放。我看不出 Step Functions 是如何工作的,如果可能的话,协调跨多个 Lambda 实例的分段上传似乎很容易出错。

标签: python amazon-web-services amazon-s3 aws-lambda boto3


【解决方案1】:

您可以使用 S3 复制功能。这将允许您复制第一个 S3 中的信息并将其复制到不同的 AWS 区域(跨区域复制),或者您可以跨同一 AWS 区域中的存储桶复制对象。 此功能在 S3 上可用,如下图所示。

现在,Lambda 中的 15 分钟限制是硬性限制。此外,如果您的代码持续时间超过 15 分钟,那么 lambda 就不是一个合适的解决方案。

【讨论】:

  • 有趣的解决方案。我会看看这个它可能会起作用。该脚本中还有一些逻辑,我没有包括在内,但我也许可以使用它来帮助在存储桶之间移动文件。
  • 祝你好运!如果您需要更高级的东西,可能需要使用 EC2 或 StepFunctions。
  • 使用复制是个好主意。需要考虑的一些事项:您需要一种方法来删除原始对象复制完成之后。复制需要打开版本控制,因此您需要有意删除源对象的正确版本,而不是对象本身。另请注意,也需要在 destination 存储桶中打开版本控制,这可能会使在那里完成的事情变得复杂。也许通过 destination 存储桶上的 AWS Lambda 函数触发删除,该函数返回并删除 source 存储桶中的对象?
  • 我回顾了设计需求,发现 S3 复制确实是实现 90% 的最简洁的方法。一个更简单的解决方案处理了最后 10%。
【解决方案2】:

一个非常简单的解决方案是使用 Amazon EC2 实例而不是 AWS Lambda 函数。

如果您可以将文件放在第一个存储桶中一段时间​​,那么您可以简单地定期运行实例(例如,一天两次)。如果您需要它更快地工作,您可以有一个 Lambda 函数,当出现新文件时启动 EC2 实例

Amazon EC2 实例的成本实际上相当低。 t2.nano 实例只有 $0.0058 per Hour 并且您只需按每秒付费。

流程是:

  • Amazon S3 事件在创建新对象时触发,该对象运行 AWS Lambda 函数
  • AWS Lambda 函数启动现有的 Amazon EC2 实例
  • EC2 实例/var/lib/cloud/scripts/per-boot/ 中有一个脚本,它会在每次启动时自动执行(不仅仅是第一次启动):
aws s3 mv --recursive . s3://target-bucket/
aws s3 mv --recursive . s3://target-bucket/
sudo shutdown now -h

这会将文件移动到目标存储桶,这意味着文件被复制然后删除。如果多个文件彼此靠近上传,则不会出错,因为 Lambda 函数只会尝试启动已启动的实例。 mv 行是有意复制的,以便在复制期间上传更多文件时再次运行。 (它可以更聪明地编写来检查文件并保持循环。)

虽然t2.nano 实例的网络带宽有限,但它应该足以复制大型对象,因为它只是将CopyPart() 消息发送到 S3,而不是传输数据本身。

【讨论】:

  • 我赞成这个解决方案,以后可能会标记为解决方案。这将允许我转换我已经构建的大部分逻辑。我想我还可以同时使用 S3 事件触发器和 cloudwatch cron 触发器来确保没有任何东西坐得太久(皮带+吊带)。此解决方案简单且几乎无服务器。我确实还有其他一些可能需要 Fargate/ECS 的任务,所以我可以在那里再次重建它作为培训/学习项目。谢谢。
  • 是的,您当然可以使用 Fargate 代替 EC2 实例。
猜你喜欢
  • 1970-01-01
  • 2012-03-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-21
  • 1970-01-01
  • 2018-04-30
  • 1970-01-01
相关资源
最近更新 更多