使用断点续传功能将大文件上传到S3

22

(我对Amazon AWS/S3还不熟悉,请耐心等待)

我的最终目标是允许用户使用网络浏览器将文件上传到S3,我的要求如下:

  1. 必须处理大文件(2GB+)
  2. 必须支持暂停/恢复和进度指示器
  3. (可选但理想!)如果连接暂时中断,能够恢复上传

我的两个问题是:

  • 我已经阅读了关于S3分段上传的文章,但不清楚如何为基于Web浏览器的上传实现暂停/恢复。

这对于大文件来说是否可能?如果可以,如何实现?

  • 我应该上传文件到EC2,然后在完成后将它们移动到S3吗?我能否(安全地)直接上传文件到S3,而不使用临时Web服务器?

如果可以直接上传到S3,如何处理暂停/恢复?

PS. 我正在使用PHP 5.2+


2
是的,您可以安全地让访问者上传到S3,而不必透露您的Amazon AWS凭据,方法是在您的服务器上创建HMAC签名,然后由访问者的浏览器使用该签名直接上传到S3。请参阅此处:http://docs.amazonwebservices.com/AmazonS3/latest/dev/UsingHTTPPOST.html 但是,我不知道是否可以与暂停/恢复上传相结合。 - Alfred Godoy
2个回答

14

更新20150527

AWS SDK for JavaScript (in the Browser)现已提供支持Amazon S3的功能,包括一个ManagedUpload类来支持当前需求中的多部分上传方面(更多信息请参见前面更新内容)。因此,它可能是您情况下最佳的解决方案。例如,可以查看使用File API上传本地文件的简明示例,该示例反过来使用了HTML5 File API - 介绍性博客文章在AWS SDK for JavaScript中宣布Amazon S3托管上传器提供了有关此SDK功能的更多详细信息。

更新20120412

我的初始答案显然忽略了主要问题,因此澄清一下:

如果您想通过简单的HTML表单进行基于浏览器的上传,则只能使用POST对象操作,它使用HTML表单将对象添加到指定的存储桶中

POST是PUT的替代形式,允许基于浏览器的上传作为将对象放入存储桶的方法。通过HTTP头传递给PUT的参数改为以multipart / form-data编码的消息正文中的表单字段传递给POST。[...]

上传在此处处理为单个操作,因此不支持暂停/恢复,并将您限制为最初的最大对象大小为5千兆字节(GB)或更少

你只能通过使用REST API进行多部分上传来克服这两个限制,而SDK(如AWS SDK for PHP)则使用它来实现此功能。
显然,这需要一个服务器(例如在EC2上)来处理通过浏览器发起的操作(这还允许您轻松地促进S3 Bucket Policies和/或IAM Policies以进行访问控制)。
一种替代方案可能是使用JavaScript库并在客户端执行,例如请参考jQuery Upload Progress and AJAX file upload。不幸的是,AWS没有官方的JavaScript SDK可用(aws-lib令人惊讶地甚至还不支持S3) - 显然,knox的一些分支已经添加了多部分上传功能,例如slakis's fork,但我尚未将它们用于手头的用例。

初步回答

如果可以直接上传大文件到S3,如何处理暂停/恢复?

AWS SDK for PHP通过Low-Level PHP API for Multipart Upload支持将大文件上传到Amazon S3:

AWS SDK for PHP公开了一个低级API,它与Amazon S3 REST API for multipart upload非常相似(请参见使用REST API进行多部分上传)。在需要暂停和恢复多部分上传、在上传过程中变化部分大小或不知道数据大小的情况下,请使用低级别API。当您没有这些要求时,请使用高级API(请参见使用高级PHP API进行多部分上传)。 [我强调]

Amazon S3可以处理从1字节到5 TB的对象,详情请参见相应的介绍文章Amazon S3 - Object Size Limit Now 5 TB
[...]现在客户可以将极大的文件作为单个对象存储,这极大地简化了他们的存储体验。Amazon S3为我们的客户在幕后进行簿记,因此您现在可以像获取任何其他Amazon S3对象一样获取该大对象。
要存储更大的对象,您需要使用我上个月博客中介绍的新Multipart Upload API来上传对象的各个部分。[...]

但是能否将这个多部分内容移植到JavaScript(或Flash/ActionScript)并在浏览器中完成,而不泄露AWS凭据? - Alfred Godoy
1
@style-sheets: 除了直接使用S3 REST API进行客户端JavaScript解决方案之外,没有其他避免这个问题的方法;我认为从成本/性能上来说,这并不是什么大问题,因为EC2到S3的连接在一个区域内相当快且免费。显然,这种方法将暂停/恢复问题转移到HTML表单中,这又需要JavaScript以及支持文件API的现代浏览器 - 也许如何恢复暂停或中断的文件上传可以帮助您入手。 - Steffen Opel
2
@style-sheets 我相信你可以使用浏览器插件,如flash、silverlight或java,并直接使用REST API来完成这个任务。我目前使用silverlight插件将大文件(高达5GB)直接上传到S3。我还没有实现暂停/恢复,也没有使用S3大文件支持,但应该是可能的。使用插件是实现广泛浏览器覆盖率的唯一方法。请查看这个SO线程https://dev59.com/-HRB5IYBdhLWcg3w4bGv。那里有许多链接指向各种免费和非免费的插件。 - Geoff Appleford
1
今天有官方的 JS SDK。 同时,还有一个智能的 multipart upload API 可供使用。 - Alex
@Alex - 感谢你的提醒/指针,我已经相应地更新了我的答案。 - Steffen Opel
显示剩余5条评论

0

我不知道有任何闪存上传器提供比标准HTTP Post更强大的功能,但您可以为客户端开发自己的Flash软件,并在服务器上配合软件。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接