将所有对象复制到具有不同结构的不同区域中的另一个S3存储桶

时间:2018-06-20 21:45:27

标签: amazon-web-services amazon-s3

我在区域A中有一个S3存储桶,其结构如下:

ProviderA-1-1
    31423423.jpg
ProviderB-1-1
    32423432.jpg

顶级文件夹是唯一的图像标识符。文件名是图像的版本

我想将图像复制到B区的存储桶中,其结构如下:

ProviderA-1-1.jpg
ProviderB-1-1.jpg

例如,我不在乎版本。我只希望文件夹名称(唯一)是文件名。

我这样做的原因是要有一个扁平的结构来利用图像服务,例如Imgix / ImageKit。 (在给定平坦来源的情况下,它们可以对图像进行即时图像转换)

所以,我的要求是:

  1. 我需要复制大量图像(数百万张图像,〜10TB)
  2. 目标存储桶在另一个区域
  3. 我需要“展平”结构,并将图像的名称更改为它们所在的文件夹的名称(文件夹名称不固定)

我在这里看到了一些答案,暗示aws cli是最好的方法,但不确定如何才能实现3.。

像我这样的声音需要一张一张地遍历图像,在复制之前更改名称。如果建议使用脚本,那么我对.NET最为满意-那么也许是AWS .NET SDK?

这是一次休息的工作,在这里我需要尽可能快且便宜地移动图像。

请咨询?

谢谢:)

2 个答案:

答案 0 :(得分:1)

假设您没有为存储分区设置位置限制,则展平将简单地是:

docker run

假设您拥有CLI installed,并正确要求credentials setup。或者,您可以在命令行中传递它们:

aws s3 cp --recursive s3://source_bucket/foo/ s3://target_bucket/

您没有提到任何性能要求。有许多方法可以使传输速度更快,这取决于许多因素。我能给出的一些盲目的提示是:

  • 看看transfer acceleration是否可以帮助您。
  • 通常,从S3到S3的传输要比从S3到非S3位置的传输要快。
  • 查看是否可以按前缀创建并行批处理,例如:

aws --profile profile_A2B --region XXX s3 cp --recursive s3://source_bucket/foo/ s3://target_bucket/ --acl yyy

如果这不是一次传输,并且传输加速不能为您节省时间,请考虑:

  • 从S3(在区域A中)下载到驻留在区域A中的本地HDD。
  • 使用其他方法,例如AsperaFileCatalyst或其他任何可以找到的方法,将区域A中的本地HDD转移到区域B中的本地HDD。
  • 从区域B中的本地HDD上载到区域B中的S3。

除了Aspera将FTP之类的东西吹倒了,我没有其他实用数据可分享,这甚至不是竞争。 YMMV。


John已经介绍了伪代码。我将对其进行更改。编写两个单独的程序,一个程序获取文件名列表,第二个程序复制。如果您有数百万个文件,则列出文件需要花费大量时间。

列出文件中的文件名(每行一个)后,只要您可以分割文件(例如for prefix in {a..z} do aws s3 cp --recursive s3://source_bucket/foo/${prefix}* s3://target_bucket/ & done ),并行化就非常容易。

使用split -l 1000 file_list splits或开枪xargs -P一次运行多个parallel命令。如果您使用的是Shell而不是.NET。

最后,不要忘记在复制过程中在目标文件上设置ACL(以及其他属性,例如TTL等)。复制后执行此操作将花费很长时间。

答案 1 :(得分:1)

是的,因为要移动和重命名文件,所以需要脚本。

如果您对.NET感到满意,请使用它!

基本程序为:

  • 创建两个S3 clients -一个用于源存储桶(以获取清单),另一个用于目标存储桶(因为复制命令已发送到目标存储桶,这会从源存储桶中提取文件),因为正在使用其他地区
  • 使用ListObjects()获取源存储桶的列表。请注意,它将一次返回1000个文件,因此请使用NextMarker请求后续的批处理。
  • 浏览每个文件,并使用CopyObject()同时复制和重命名该文件。使用您自己的逻辑获取文件夹名称并将其转换为文件名。每个文件将直接在存储桶之间复制,而无需下载/上传
  • 继续,遍历1000个文件的列表,然后获取下一个1000个文件,等等。

可以通过使用多线程来加速该过程,但是逻辑有些困难。同时运行几个程序副本可能会更容易,每个副本处理不同的Prefix范围(实际上是文件夹名称)。

这是一项一次性的工作,因此优化并不重要。

如果以后要添加更多文件,最好的方法是创建一个 AWS Lambda函数,该函数在S3中创建新文件时就会触发。然后,Lambda函数会将文件复制到目标位置,然后退出。