如何在一次调用中从AWS S3复制许多文件而无需递归?

时间:2019-04-01 21:46:10

标签: amazon-web-services amazon-s3 aws-cli

我需要从aws s3复制许多文件(> 10,000)。这个存储桶包含数十万个文件,我不想下载所有文件。 随着新文件频繁进入存储桶,该过程需要每小时/通过编程自动重复一次。

使用本机awscli参数可以找到的唯一受支持的方法是:

  1. 使用aws s3 cp --recursive s3://the_bucket/ local_location选项。因为存储桶中包含成千上万个文件,所以此过程会下载许多我不想要的文件,而且速度很慢。
  2. 使用aws s3 sync。这种方法只下载我想要的文件,但速度很慢。如果存储桶仅更新了几个文件,sync必须检查整个存储桶中是否有新文件。这非常慢。
  3. 使用aws s3 ls s3://the_bucket/ local_location查找存储桶中的所有文件,并将其与我以前不想再次下载的文件索引进行比较。 aws s3 ls很快,但是,我不得不aws s3 cp s3://the_bucket/the_file local_location一个一个地打电话,这很慢。

tl; dr

如何在不使用递归的情况下(即多次aws s3或多次调用aws s3 cp --recursive s3://the_bucket/ local_location)从awscli存储桶中复制所需的许多文件?

3 个答案:

答案 0 :(得分:2)

确实,您处于困境中。

一旦存储桶中的对象数量增加,将需要很长时间才能列出它们。列表对象的API调用一次仅返回1000个对象。 aws s3 syncaws s3 cp ...*命令都需要列出对象才能复制它们。

一种替代方法是使用Amazon S3 Inventory - Amazon Simple Storage Service,它可以提供每天列出所有对象的CSV文件,但这似乎不能满足您每小时下载一次新文件的要求。

一种更复杂的方法(但可以使用)是每当创建新对象时创建一个Amazon S3事件。然后,您可以通过以下两种方式之一处理事件:

  • 将事件推送到 Amazon SQS队列。然后,每小时运行一个程序,该程序将处理队列中的消息并复制文件
  • 为每个事件触发一个 AWS Lambda函数。 Lambda函数可以向数据库添加详细信息,然后每小时可以使用它来获取要复制的文件列表。

答案 1 :(得分:0)

一个实际的解决方法是,每小时创建一个带有时间戳的目录,并将新文件存储在该目录中。然后,您只需处理存储桶中的最新时间戳目录。

答案 2 :(得分:0)

根据您的具体情况(对AWS资源的访问非常有限)和您的观察

  

使用aws s3 ls s3:// the_bucket / local_location查找存储桶中的所有文件,并将其与我以前不想再下载的文件索引进行比较。 aws s3 ls非常快,但是,我必须一一调用aws s3 cp s3:// the_bucket / the_file local_location,这非常慢。

我相信第三选择是最好的选择,尽管有一些评论

1 /

  

ThrowExcIfNull很快

您可能要确保获得所需的所有文件,并且确实与观察到的速度一样快。当返回的键数超过1000时,您需要处理标记/分页以进行更多呼叫

2 /

  

我必须打aws s3 ls   一张一张,很慢。

在进行自动化时,它的速度不应该慢于系统的速度。您很可能仅会受到Internet带宽的限制。如果您有大量的小文件,请考虑执行多进程,并同时配置concurrent aspect of the CLI