16

我有一些文件正在上传到 S3 并针对某些 Redshift 任务进行处理。该任务完成后,需要合并这些文件。目前我正在删除这些文件并再次上传合并文件。这些会占用大量带宽。有什么办法可以直接在 S3 上合并文件?

我正在使用 Apache Camel 进行路由。

4

2 回答 2

29

S3 允许您使用 S3 文件 URI 作为复制操作的源。结合 S3 的多部分上传 API,您可以提供多个 S3 对象 URI作为多部分上传的源键。

然而,魔鬼在细节中。S3 的分段上传 API 的最小文件部分大小为 5MB。因此,如果串联文件系列中的任何文件小于 5MB,它将失败。

但是,您可以通过利用允许最终上传片段小于 5MB 的循环漏洞来解决此问题(允许这样做是因为在现实世界中上传剩余片段时会发生这种情况)。

我的生产代码通过以下方式执行此操作:

  1. 查询要上传文件的清单
  2. 如果第一部分小于 5MB,则下载片段*并缓冲到磁盘,直到缓冲 5MB。
  3. 依次追加部分,直到文件连接完成
  4. 如果非终端文件小于 5MB,请附加它,然后完成上传并创建新的上传并继续。

最后,S3 API 中存在一个错误。ETag(实际上是 S3 上的任何 MD5 文件校验和,在完成多部分上传时未正确重新计算。要解决此问题,请在完成时复制罚款。如果您在连接期间使用临时位置,这将得到解决关于最后的复制操作。

*请注意,您可以下载文件的字节范围。这样,如果第 1 部分为 10K,第 2 部分为 5GB,则只需读取 5110K 即可满足继续所需的 5MB 大小。

**您还可以在 S3 上拥有一个 5MB 的零块并将其用作您的默认起始部分。然后,上传完成后,使用字节范围进行文件复制5MB+1 to EOF-1

PS 当我有时间制作这段代码的要点时,我会在此处发布链接。

于 2015-10-18T17:07:14.270 回答
14

您可以使用Multipart Upload with Copy来合并 S3 上的对象,而无需再次下载和上传它们。

您可以在此处找到一些 Java、.NET 或 REST API 示例。

于 2013-10-11T20:54:48.317 回答