【问题标题】:Why should(n't) I use S3 instead Lambda for static content为什么应该(不)我使用 S3 而不是 Lambda 来处理静态内容
【发布时间】:2017-11-06 16:08:32
【问题描述】:

让我们想象一下这样的情况:

我们有 node.js 应用程序,它在服务器端呈现视图并将 html 发送到浏览器。在生成的 html 中,我们几乎没有静态资源(如图像、样式表等)。

为什么我应该(或不)选择 S3 而不是 Lambda 来提供此内容?

以下是我看到的利弊:

性能

我很确定从 S3 提供内容比从 Lambda 提供内容要快得多(没有需要执行的脚本)...

...直到我执行了一些平均 10 个请求的测试(文件大小约为 44kB):

  • API GW + S3:285 毫秒
  • API GW + Lambda:290 毫秒
  • S3:135 毫秒

如您所见,通过 API GW 从 Lambda 提供内容与从 S3 提供内容没有区别。唯一显着的区别是直接链接到 s3 和之前的两个测试之间。

Lambda 1 : S3 1

费用

这里 Lambda 绝对胜出。

首先,我们有 1 000 000 个请求的免费分类, 其次是定价:

  • S3:每 10,000 个请求 0.004 USD
  • Lambda:每 10,000 个请求大约 0,002000624:

(每 100 万次请求 0.20 美元 + 每 100 毫秒 0.000000208 美元)

所以在定价方面 Lambda 胜出。

总结

我的观察表明,Lambda 甚至是提供静态内容的更好方法(速度与 S3 相似,价格便宜两倍)。

我有什么遗漏的吗?

【问题讨论】:

  • 您关于计算(或)数据传输的计算可能是正确的,但在 Lambda 案例中,您的“静态内容”会是什么?我不清楚。
  • 我只是用 .zip 包把它提供给云端
  • 我希望您知道 CloudFront 的成本高于 S3(除非您需要更快的响应时间)。我对 CloudFront 配置没有太多经验,但根据我的理论知识,它不需要一个“存储”来同步“静态内容”吗?
  • 哦.. 我想到的是 CloudFormation,而不是 CloudFront :) 抱歉
  • CloudFormation 对于内容的“存储”毫无用处。那么,现在您需要一种方法来保持“静态内容”正确吗?这就是 S3 的用途。 Lamda 和 S3 用于 2 个不同/不同的目的。

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


【解决方案1】:

我相信你犯了几个错误。

S3 请求定价为每 10,000 个请求 0.004 美元,即每百万个 0.40 美元。没错。

Lambda 是每百万次调用 0.20 美元,加上 CPU 时间。同意。

但我相信您忽略了一个事实,即您无法在没有 API Gateway 的情况下从 Internet 调用 Lambda 函数,每百万个请求需要额外支付 3.50 美元。

从 Lambda 提供静态内容的净成本为每百万个请求 3.70 美元,加上 CPU 时间。¹

这大大降低了 S3 的成本。

然后,考虑带宽成本:CloudFront 与 S3 结合使用时,比单独使用 S3 更快,每个请求的成本更高,但带宽成本也略低。如果您将 CloudFront 分配限制为 Price Class 100,那么在某些情况下,您实际上会比仅使用 S3 支付更少的费用。

最便宜地区的 S3 下载带宽为 0.09 美元/GB。

最便宜级别的 CloudFront 下载带宽为 0.085 美元/GB。

从 S3 到 CloudFront 的带宽是免费的(例如缓存未命中)。

将 CloudFront 与 S3 结合使用时,每 GB 下载的成本比单独使用 S3 时低 0.005 美元。 CloudFront 每 10,000 个请求收取 0.0075 美元,或者比 S3 多 0.0035 美元...但是,如果我们假设缓存命中率为 50%,则数字如下所示:

每 10,000 个对象 $0.0075 [CF] + ($0.004 [S3] * 0.5 [命中率]) = $0.0095...为简单起见,我们将其四舍五入为 $0.01。

现在,我们可以看到 10K 对象的请求成本完全被节省的 2GB 下载量所抵消,因此如果您的对象大于 2G/10K = 2M/10 = 200KB/每个,那么将 CloudFront 与 S3 结合使用是实际上比单独使用 S3 便宜一点。如果不是这样,成本仍然太接近而不会显着,并且如前所述,下载周转时间要短得多。

此外,CloudFront 支持 HTTP/2。


¹ 这假设 API Gateway + Lambda。由于编写了此答案,现在还有两种方法可以让 Lambda 函数返回静态(或动态)内容:来自 Lambda 函数的CloudFront's Lambda@Edge feature supports generating HTTP responses,但该函数在仅支持的特殊、轻量级“边缘”容器中运行节点.js。但是,这里的最小运行时间是 50 毫秒,而不是标准的 100 毫秒。 Application Load Balancers also support using a Lambda function as a target,这些是标准容器中的标准 Lambda 调用,因此支持所有运行时。这两者都可能比 API Gateway 更具成本效益,尽管除非您已经拥有 ALB,否则还必须考虑 ALB 本身的基线成本。两者都限制为 1MB 响应正文(在 Lambda@Edge 上,这需要“源请求”触发器),这比 API Gateway 的限制更小。

【讨论】:

  • 你好。感谢您的回答。我没有考虑 API GW 的价格,因为我假设两个流量(S3 和 Lambda)都会通过 API GW。据我了解您的回复,当您的应用程序负载较大时,S3 + CF 是更好的选择。你不认为通过 API GW + Lambda 提供内容的小型应用程序(每天 100 名访问者)更便宜吗?
  • 我明白你的意思。除非您的静态资产需要得到保护,否则我认为没有必要走那条路……但是,如果它对您有用,我都赞成以非常规的方式使用服务,如果它有意义并且性能是可以接受的......我已经做过很多次了。我实际上已经尝试过使用 API Gateway 的“模拟迭代”功能从“集成响应”映射模板呈现基于文本的静态内容。为什么?为什么不呢?
  • 是的。明确地。我刚刚完成了在 Lambda + API GW 上运行的 angular-universal 的 biolerplate。你可以在这里查看:github.com/maciejtreder/angular-universal-serverless
【解决方案2】:

您可能需要考虑的另一个重要因素是 lambda 冷启动时间,它会影响您的性能。对于静态资源,它可能会显着增加页面加载时间。如果您的 lambda 恰好是基于 vpc 的,这会变得更糟,这需要附加一个新的 ENI,这需要更长的时间来创建。

【讨论】:

    猜你喜欢
    • 2016-05-23
    • 1970-01-01
    • 2018-05-10
    • 2014-03-12
    • 2012-12-13
    • 2013-11-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多