【问题标题】:Cloudfront TTL not workingCloudfront TTL 不起作用
【发布时间】:2014-10-30 20:01:36
【问题描述】:

我遇到问题并尝试在论坛中关注答案,但没有任何成功。

为了生成缩略图,我设置了以下架构: 原始图像的 S3 帐户 使用 NGINX 和 Thumbor 的 Ubuntu 服务器 云端

用户将原始图片上传到S3,将通过Ubuntu Server拉取,请求前面有Cloudfront:

http://cloudfront.account/thumbor-server/http://s3.aws...

重要的是,我们经常在 Cloudfront 中丢失对象,我希望它们在缓存中保留 360 天。 我通过 Cloudfront URL 得到以下响应:

Cache-Control:max-age=31536000
Connection:keep-alive
Content-Length:4362
Content-Type:image/jpeg
Date:Sun, 26 Oct 2014 09:18:31 GMT
ETag:"cc095261a9340535996fad26a9a882e9fdfc6b47"
Expires:Mon, 26 Oct 2015 09:18:31 GMT
Server:nginx/1.4.6 (Ubuntu)
Via:1.1 5e0a3a528dab62c5edfcdd8b8e4af060.cloudfront.net (CloudFront)
X-Amz-Cf-Id:B43x2w80SzQqvH-pDmLAmCZl2CY1AjBtHLjN4kG0_XmEIPk4AdiIOw==
X-Cache:Miss from cloudfront

重新刷新后,我得到:

Age:50
Cache-Control:max-age=31536000
Connection:keep-alive
Date:Sun, 26 Oct 2014 09:19:21 GMT
ETag:"cc095261a9340535996fad26a9a882e9fdfc6b47"
Expires:Mon, 26 Oct 2015 09:18:31 GMT
Server:nginx/1.4.6 (Ubuntu)
Via:1.1 5e0a3a528dab62c5edfcdd8b8e4af060.cloudfront.net (CloudFront)
X-Amz-Cf-Id:slWyJ95Cw2F5LQr7hQFhgonG6oEsu4jdIo1KBkTjM5fitj-4kCtL3w==
X-Cache:Hit from cloudfront

我的 Nginx 响应如下:

Cache-Control:max-age=31536000
Content-Length:4362
Content-Type:image/jpeg
Date:Sun, 26 Oct 2014 09:18:11 GMT
Etag:"cc095261a9340535996fad26a9a882e9fdfc6b47"
Expires:Mon, 26 Oct 2015 09:18:11 GMT
Server:nginx/1.4.6 (Ubuntu)

为什么 Cloudfront 不按指示存储我的对象? Max-Age 设置了吗? 非常感谢。

【问题讨论】:

  • 您可能没有访问相同的 Cloudfront 位置。每个位置都会单独缓存文件,直到所有位置都有您要缓存的文件,它仍然可以从源中检索它。
  • 我已经尝试了好几次,甚至还创建了一个小型 java 应用程序——在我看来,缓存会刷新。一段时间后我已经设置了 max-age,但我认为它会被现有的元素覆盖?

标签: amazon-web-services amazon-s3 amazon-cloudfront ttl


【解决方案1】:

您的第二个请求显示该对象确实已缓存。我假设你看到了,但问题并没有说清楚。

Cache-Control: max-age 仅指定您的对象在任何特定边缘位置的 Cloudfront 缓存中的最长年龄。没有保证您的对象可以持续存在的最小时间间隔……毕竟,Cloudfront 是一个缓存,根据定义它是可变的。

如果边缘站点中的对象不经常被请求,CloudFront 可能会驱逐该对象(在其到期日期之前移除该对象),以便为更受欢迎的对象腾出空间。

——http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/Expiration.html

此外,Cloudfront 没有作为一个整体拥有您的对象副本的概念。每个边缘位置的缓存似乎都独立于其他位置运行,因此经常会看到来自不同 Cloudfront 边缘位置对相对流行的对象的多个请求。

如果您尝试调解后端服务器上的负载,则在其前面放置某种您控制的缓存可能是有意义的,例如 varnish、squid、另一个 nginx 或自定义解决方案,是我如何在我的系统中实现这一点的。

或者,您可以在处理后将每个结果存储在 S3 中,然后将现有服务器配置为首先检查 S3,然后再次尝试调整对象大小的工作。


那为什么要记录“最小” TTL?

在上面引用的同一页面上,您还会发现:

对于 Web 分配,如果您将 Cache-Control 或 Expires 标头添加到您的对象,您还可以指定 CloudFront 在将另一个请求转发到源之前将对象保留在缓存中的最短时间。

我可以明白为什么会这样,以及下面评论中引用的提示短语...

在 CloudFront 将另一个请求转发到您的源以确定更新版本是否可用之前,对象在 CloudFront 缓存中的最短时间(以秒为单位)。

...似乎与我的回答相矛盾。然而,这并不矛盾。

简单来说,最小 ttl 为 Cache-Control: max-age 的内部解释建立了一个下限,覆盖了 - 在 Cloudfront 中 - 源服务器发送的任何较小的值。服务器说缓存它最多 1 天,但配置的最小 ttl 是 2 天? Cloudfront 忘记了它在 max-age 标头中看到的内容,并且可能不会在接下来 2 天的后续请求中再次检查来源,而不是在 1 天后再次检查。

缓存的性质决定了对所有明显歧义的正确解释:

您的配置限制了 Cloudfront 可以提供对象的缓存副本的时间,以及它不应继续从其缓存中返回对象的时间点。他们没有规定 Cloudfront 必须维护缓存副本多长时间,因为 Cloudfront 可以随时驱逐对象。

如果您正确设置了 Cache-Control: 标头,Cloudfront 将考虑较大的 max-age 或您的最小 TTL 作为您希望他们提供缓存副本而无需再次咨询源服务器的最长时间。

随着您的网站流量增加,这应该不再是一个问题,因为您的对象会更“流行”,但基本上没有办法强制 Cloudfront 维护对象的副本。

【讨论】:

  • 感谢您的好评。我已在管理控制台中将 Min TTL 设置为 31536000,至少对于我的理解如下:在 CloudFront 将另一个请求转发到您的源之前,对象在 CloudFront 缓存中的最短时间(以秒为单位)确定是否有可用的更新版本。默认时间为 24 小时。要更改对象在缓存中的时间,请配置您的源以添加 Cache-Control max-age 指令。请参阅帮助。
  • 我明白为什么这似乎在说一些与实际意思不同的东西。更新了答案。
  • 所以您的建议是使用 NginxCache 或 Varnish 而不是 CDN。据我了解您更新的帖子,无法强制 CloudFront 将其保留 x 秒。
  • 不,不是“代替”。 “此外。” Cloudfront 非常有价值且速度很快,但如果您的动机是让您调整服务器大小以尽可能少地查看请求,那么您可能需要在 cloudfront 和调整大小之间建立一个缓存。我开发了一个产品/服务,通过使用 S3 作为“无限大小的缓存”来做到这一点。 Cloudfront 击中我,我检查 S3 并在找到时返回结果,否则我将请求发送到后端,将响应返回给请求者,然后在 S3 中保存一份副本以供将来请求。
  • @Michael-sqlbot 我们在哪里可以找到有关此服务的信息?谷歌搜索时,您的个人资料没有链接,“sqlbot”似乎是您首选的互联网名称,而不是公司。
猜你喜欢
  • 2022-01-05
  • 1970-01-01
  • 2017-01-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-24
  • 1970-01-01
  • 2017-07-20
相关资源
最近更新 更多