用于从多个端点将大文件上传到云存储的架构

Architecture for uploading large files from many end points to the cloud storage

我正在开发一个提供上传到云存储的桌面应用程序。存储提供商有一种简单的方法来上传文件。你得到 accessKeyId 和 secretAccessKey 就可以上传了。我正在尝试想出上传文件的最佳方式。

选项 1. 使用访问密钥打包每个应用程序实例。这样文件就可以直接上传到云端,无需中间人。不幸的是,我无法在上传到云端之前执行任何逻辑。例如.. 如果每个用户都有 5GB 的可用存储空间,我无法在存储提供商处验证此约束。我还没有找到任何供应商这样做。我可能会在上传之前向我自己的服务器发送请求以进行验证,但由于密钥是硬编码在应用程序中的,我确信这是一个简单的漏洞利用。

选项2.将每个上传的文件发送到服务器,在服务器上可以执行约束逻辑并将文件转发到最终的云存储。这种方法在服务器上存在瓶颈。例如,如果 100 个用户开始上传(或下载)1 GB 文件并且如果服务器的带宽速度为 1000Mb/s,则每个用户上传速度仅为 10Mb/s = 1.25MB/s。

选项 2 似乎是可行的方法,因为我可以控制谁可以上传并且密钥不会公开共享。我正在寻找最小化带宽瓶颈的技巧。建议使用什么方法来处理同时将大文件上传到云存储?我正在考虑部署许多低 cpu 和低内存实例并使用流式传输而不是先缓冲整个文件然后再发送它。

我认为要求体系结构验证和改进超出了本论坛的范围,但我会坚持下去。另外,有些方面还不清楚。我假设您的意思是您会将文件上传到 S3 之类的东西,但您会根据用户支付的金额限制用户可以上传的数量。

您可以使用选项 1。直接上传到存储提供商,但首先要通过您的服务器进行验证。您需要能够:

  • 识别每个用户。一个简单的 UUID 可能会成功,或者完整 user/pass.
  • 有一个数据库来跟踪每个客户端的使用情况。
  • 使用您自己的私钥加密桌面应用程序和您的服务器之间的通信。也就是说,除了 HTTPS。如果您不清楚 public-key cryptography 的工作原理,您应该查一下。
  • 为每个提供者使用临时访问密钥并找到处理方法。

这些会增加你的成本。虽然不像选项 2 那样多。

您的应用程序将在上传之前对您的服务器进行 API 调用,以确定上传是否有效。任何不是好的答案(或缺少答案)都意味着上传失败。这也意味着您在架构中引入了单点故障,并且您最好确保只要您仍然有用户,您的服务器就始终可用,否则您将违反惠顿定律。我的建议,在这里使用无服务器。

您将使用临时 access_key/secret_key 对上传文件。桌面应用程序会将文件直接上传到您正在处理的任何提供商,但它会使用每 12 小时更改一次的 key/secret 对。每个用户都有自己的一对,您需要确保用户只能访问自己的文件。否则他们将能够访问每个人的文件,而您将违反惠顿定律。这样,即使他们以某种方式弄清楚了秘密是什么,他们最多也只能访问 12 小时,之后您将更改密钥并切断它们。

应用程序和您的服务器之间的所有通信都使用 public 密钥加密法加密。私钥存储在您的服务器上,用户获得 public 密钥。这样您就可以在需要时轻松更新加密密钥,因为 public 密钥是 public。请记住,这提供了加密,而不是身份验证。

您可以轻松地使用户的访问无效,方法是更改​​他们的 access_key/secret_key 对用于直接与服务器提供商通信以及用于与您的服务器通信的私钥。

您的服务器应跟踪每个用户的文件并验证服务器端数据库中的内容与存储中的内容相同。定期做。每天、每周、每 2 小时,任何适合您的方法。如果您发现不一致,请进行调查。也许他们想作弊。或者您的应用可能存在错误。这意味着您必须能够在存储级别识别哪个文件属于哪个用户。这就像用用户的 UUID 将用户的所有文件存储在一个目录中一样简单。不要在那里使用姓名或电子邮件。除了您的数据库之外,任何个人身份数据都不应存储在其他任何地方。即使在那里,也只有在需要时才应该加密。

所以,它是这样的:

  1. 桌面应用程序向您的服务器发送一条消息,要求上传文件。类似于 "I need to upload a 3.7 GB file"。消息在使用该用户的 public 密钥发送之前被加密。
  2. 您的服务器获取消息、对其进行解密、检查 space 是否可用、在其数据库中查找合适的提供者并检索该提供者的最新 access_key/secret_key。
  3. 您的服务器发送类似 "ALL_GOOD, upload to provider_AWS_S3, using THIS_ACCESS_KEY paired with THIS_SECRET_KEY" 的内容。消息使用私钥加密。
  4. 桌面应用程序使用提供的密钥将文件直接上传到 S3。

下载等操作同理。

无服务器的绝佳用例(AWS 上的 Lambda、Google 函数等),这将降低成本并提供更高的冗余度和 "uptime"。

可以改进,也有陷阱。例如,在上传之前加密文件客户端会增加额外的安全层。但是这个 post 已经太长了。

给你。那将是 3000 美元 :).