我正在开发一个包含文件存储和共享功能的项目,经过数月研究利用AWS的最佳方法后,我仍然有点担心。
基本上我的决定是使用EBS存储来存放用户文件或S3。当用户想要下载少量文件时,系统将包含即时zip存档。此外,当用户下载任何文件时,我不希望URL暴露在文件中。
我提出的两个最佳选择是:
安装一个EC2实例,其中安装了许多EBS卷以存储用户文件。
上传和处理文件后,系统会将这些文件推送到S3存储桶以进行长期存储。当请求文件时,我将从S3检索文件并输出回客户端。
我的任何假设都有缺陷吗?有人能想到更好的方法来管理大量的文件存储吗?
答案 0 :(得分:21)
如果您的服务将由未确定数量的用户使用,请务必记住可扩展性始终是一个问题,无论采用何种选项,您都需要扩展服务以满足需求,因此,假设您的服务将在具有EC2实例池而不是单个实例的Auto Scaling组中运行会很方便。
关于保护URL以仅允许授权用户下载文件,有很多方法可以在不要求您的服务充当中间人的情况下执行此操作,那么您将需要处理至少两个问题:
文件名可预测:避免URL可预测性,你能说出上传文件的哈希和原始文件名和所有权存储在类似的SimpleDB数据库,您还可以选择设置一个HTTP标题,例如“Content-Disposition:filename = original_file_name.ext”,建议用户浏览器相应地命名下载的文件。
授权:当用户要求下载您的服务的给定文件时,请使用Query String Authentication或Temporary Security Credentials为该特定用户发出临时授权,以提供读访问权限到该文件一段时间后,您的服务将重定向到S3存储桶URL以供直接下载。这可以极大地卸载您的EC2池实例,从而可以更快地处理其他请求。
为了减少S3存储桶的空间和流量(请记住您支付每GB存储和传输的费用),我还建议使用标准算法(如gzip)压缩每个文件,然后再上传到S3并设置标题“Content-Encoding” :gzip“为了使用户浏览器自动解压缩。如果您选择的编程语言是Java,我建议您查看我创建的用于从Web项目上传静态资源的插件代码webcache-s3-maven-plugin。
关于压缩文件夹的处理时间,您经常无法确保文件夹在短时间内被压缩,以便允许用户立即下载,因为最终可能存在大量文件夹可能需要几分钟甚至几小时才能被压缩。为此,我建议您使用SQS和SNS服务以允许异步压缩处理,它将按如下方式工作:
在这种情况下,您可能有两个Auto Scaling组,分别是前端和后端,可能有不同的可扩展性限制。
答案 1 :(得分:5)
如果您坚持使用S3直接从EC2实例提供zip文件,那么比在本地存储它们更复杂。但S3比任何EC2存储卷都更耐用,所以如果文件需要保存很长时间,我建议使用它。
您说您不希望直接公开文件网址。如果这只是因为您不希望人们将它们加入书签并在将来绕过您的服务身份验证,那么S3有一个很好的解决方案:
1 - 在私有S3存储桶中存储您要提供的文件(如果您愿意,请将其压缩)。
2 - 当用户请求文件时,请对请求进行身份验证,然后将有效请求重定向到文件的已签名的临时S3 URL 。有很多种语言可以创建这些URL。
3 - 用户直接从S3下载文件,而不必通过您的EC2实例。这样可以节省带宽和时间,并可能为用户提供最快的下载速度。
这确实暴露了一个URL,但这可能没问题。如果用户保存URL,则没有问题,因为它在您设置的到期时间后将无法工作。对于我的服务,我将时间设置为5分钟。由于它是经过数字签名的,因此用户无法在不使签名失效的情况下更改URL中的到期时间。
答案 2 :(得分:2)
使用S3是这个用例的更好选择。它更好地扩展并且更简单。你为什么担心它很慢? EC2和S3之间的转移非常活泼。
答案 3 :(得分:0)
一些注意事项:
我会将所有内容保存在S3上,根据需要下载文件以将其压缩到一个包中。然后将zip上传到S3并向用户提供S3签名URL以从S3下载。
您可以允许用户从您的EC2实例下载,但许多用户有错误问题,重试问题,带宽缓慢等。如果zip文件很小(小于100 MB)在本地提供,否则上传到S3让S3处理用户下载问题。
另一种选择是创建一个Lambda函数,用于创建zip文件并在S3上存储。现在您不必担心网络带宽或扩展。 Lambda函数可以返回您提供给浏览器的S3 URL,或者Lambda可以通过电子邮件向客户发送链接。仔细研究SES。注意:Lambda文件系统只有512 MB的空间,内存最多可以分配1.5 GB。如果您生成大于此的zip文件,Lambda将无法正常工作(此时)。但是,您可以创建多个zip文件(part1,part2,...)
答案 4 :(得分:0)
主要问题是您在哪里托管。由于您说您使用的是 ec2 实例,这意味着您正在利用 AWS,如果您需要扩展,我会选择 EBS,然后是 EFB。
S3 很棒,但 IMO 主要适用于如果您使用不同的提供商(如 Namecheap 等)托管您的站点,并且只想将 AWS 用于数据库。
我认为可靠性持久性并不重要,尤其是当您考虑可以备份 Ec2 和 EFB 的快照时。
我只看价格。看看哪个便宜。如果存在显着的性能差异(用户等待时间为 2-5 秒),我可能会考虑花更多钱购买更快的。
EFB 是一种扩展方法,可能比 EBS 更便宜。我相信亚马逊建议使用 EBS,直到达到一定规模,然后切换到 EFB。