将文件推送到 Amazon Cloudfront:可能吗?
Posted
技术标签:
【中文标题】将文件推送到 Amazon Cloudfront:可能吗?【英文标题】:Push files up to Amazon Cloudfront: Possible? 【发布时间】:2012-05-12 06:50:13 【问题描述】:我一直在阅读有关拉取和推送 CDN 的文章。我一直在使用 Cloudfront 作为调整大小图像的拉式 CDN:
从客户端接收图片 将图像放入 S3稍后,当客户端向云端请求 URL 时,云端没有图像,因此它必须将其转发到我的服务器,其中:
接收请求 从 S3 拉取图像 调整图片大小 将图像推回 Cloudfront但是,这需要几秒钟,当您第一次上传漂亮的图片并想看到它时,这真的很烦人。延迟似乎主要是下载/重新上传时间,而不是调整大小,这非常快。
是否可以主动将调整大小的图像推送到 Cloudfront 并将其附加到 URL,以便将来的请求可以立即获取准备好的图像?理想情况下,我想
从客户端接收图片 将图像放入 S3 为常见尺寸调整图像大小 先发制人地将这些大小推送到云端这避免了整个下载/重新上传周期,使常见尺寸非常快,但仍然可以访问不太常见的尺寸(尽管第一次有延迟)。但是,要做到这一点,我需要将图像推送到 Cloudfront。这个:
http://www.whoishostingthis.com/blog/2010/06/30/cdns-push-vs-pull/
似乎暗示它可以完成,但我所看到的其他一切都没有提及它。我的问题是:有可能吗?或者我缺少这个问题的任何其他解决方案?
【问题讨论】:
【参考方案1】:我们已经尝试与不同的 CDN 提供商进行类似的事情,对于 CloudFront,我认为没有任何现有方法可以让您将您的特定内容推送(我们称之为预馈送)到节点/边缘(如果云端分发)正在使用您的自定义来源。
我能想到的一种方法,也正如@Xint0 提到的那样,设置另一个 S3 存储桶来专门托管您想要推送的那些文件(在您的情况下是那些调整大小的图像)。基本上,您将拥有两个 cloudFront 发行版,一个用于拉取那些很少访问的文件,另一个用于推送那些经常访问的文件以及您希望调整大小的那些图像。这听起来有点复杂,但我相信这是你必须做出的权衡。
我可以建议您查看的另一点是 EdgeCast,它是另一个 CDN 提供商,他们确实提供了名为 load_to_edge 的功能(上个月我花了很多时间将其与我们的服务集成,这就是为什么我记得很清楚) 这完全符合您的期望。他们还支持自定义原点拉取,所以也许你可以在那里试用。
【讨论】:
可惜;我使用 cloudfront 作为各种缓存,这大大简化了在 s3 上存储每个图像的多个版本。为公共文件维护一个单独的 dist 将使该优势变得毫无意义。我想我的下一步是尝试在原始服务器上预渲染和缓存常见的图像大小,因此第一次云端点击只需支付上传时间而不是下载调整大小上传时间跨度> 对我之前的回答的进一步评论是,CloudFront 最近开始支持同一分配的多个来源。这意味着我的两个发行版的解决方案可以保存到一个,您可以配置哪一组文件指向哪个原始 url。 有什么推荐的CDN支持push/pre-feeding的吗?【参考方案2】:OP 要求推送 CDN 解决方案,但听起来他真的只是想让事情变得更快。我敢说您可能并不真的需要实现 CDN 推送,您只需要优化您的源服务器模式即可。
所以,OP,我假设您最多支持少数几种图像尺寸,比如 128x128、256x256 和 512x512。听起来您在 S3 中也有这些图像的原始版本。
这是当前缓存未命中时发生的情况:
-
CDN 收到对 128x128 版本图像的请求
CDN 没有该图像,因此它从您的源服务器请求它
您的源服务器收到请求
您的源服务器从 S3 下载原始图像(可能是更大的图像)
您的源会调整该图像的大小并将其返回到 CDN
CDN 将该图像返回给用户并缓存它
你应该做什么:
这里有几个选项,具体取决于您的具体情况。
您可以使用当前设置快速解决以下问题:
-
如果您必须从 S3 获取原始图像,您基本上是在这样做,以便缓存未命中导致每个图像的下载时间与原始大小的图像一样长。如果可能的话,您应该尝试将这些原始图像存储在您的源服务器可以快速访问的地方。根据您的设置,这里有一百万种不同的选项,但从 S3 获取它们是所有选项中最慢的。至少你没有使用 Glacier ;)。
您没有缓存调整大小的图像。这意味着 Cloudfront 使用的每个边缘节点都会请求此图像,这会触发整个调整大小的过程。 Cloudfront 可能有数百个单独的边缘节点服务器,这意味着每个图像有数百个丢失和调整大小。根据 Cloudfront 为分层分发所做的工作,以及您设置文件头的方式,它实际上可能没有那么糟糕,但也不会很好。
我在这里有点冒险,但我敢打赌您没有设置自定义过期标头,这意味着 Cloudfront 只会将这些图像中的每一个缓存 24 小时。如果您的图片在上传后是不可变的,那么您会真正受益于返回过期标头,告诉 CDN 在很长一段时间内不要检查新版本。
以下是一些可能更好的模式的想法:
-
当有人上传新图片时,立即将其转码为您支持的所有尺寸并将其上传到 S3。然后只需将您的 CDN 指向该 S3 存储桶。这假设您拥有可管理数量的受支持图像大小。但是,我要指出,如果您支持太多图像大小,CDN 可能完全是错误的解决方案。您的缓存命中率可能非常低,以至于 CDN 确实妨碍了您。如果是这种情况,请参阅下一点。
如果您支持连续调整大小(即,我可以请求 image_57x157.jpg 或 image_315x715.jpg 等,并且服务器会返回它),那么您的 CDN 实际上可能会通过引入额外的跃点而不卸载来对您造成伤害很多来自你的起源。在这种情况下,我可能会在所有可用区域中启动 EC2 实例,在它们上安装您的源服务器,然后根据客户端 IP 将图像 URL 交换到适合区域的源(有效地滚动您自己的 CDN)。
如果你真的想推送到 Cloudfront:
您可能不需要,但如果您只是必须,这里有几个选项:
-
向use the webpagetest.org APIs 写一个脚本,从世界各地的不同地方获取您的图像。从某种意义上说,您会将拉动命令推送到所有不同的边缘位置。这不能保证填充每个边缘位置,但您可能会接近。请注意,我不确定webpagetest.org 会以这种方式使用它有多兴奋,但我没有看到任何关于它的使用条款(IANAL)。
如果您不想使用第三方或冒着惹恼webpagetest.org 的风险,只需在每个区域启动一个微型EC2 实例,并使用它们来获取内容,与#1 相同。
【讨论】:
只是为了跟进此事。我们在未来,现在有更好的解决方案可以解决这个问题。您可以考虑专门针对此问题的产品(例如 Cloudinary)。或者,如果您想继续自己管理它,您可以查看 aws Lambda 或 Route53 别名以将计算分配到边缘节点。【参考方案3】:AFAIK CloudFront 使用 S3 存储桶作为数据存储。因此,调整图像大小后,您应该能够将调整大小的图像直接保存到 CloudFront 使用的 S3 存储桶中。
【讨论】:
我已将其设置为将我的源服务器用作数据存储而不是 S3。关键是现在我不需要担心我在 S3 上占用的空间量或图像是否过期:如果有人想要特定尺寸,他们可以得到它,并且将来他们可以继续得到它(不重新渲染)24小时,直到它过期。本质上,我使用 cloudfront 作为调整大小图像的缓存(其原始副本本身存储在 S3 上)并希望预先填充它,而不是在 S3 本身上完成所有这些。以上是关于将文件推送到 Amazon Cloudfront:可能吗?的主要内容,如果未能解决你的问题,请参考以下文章
无法将图像推送到 Amazon ECR - 因“没有基本身份验证凭证”而失败
git:在 Mac 上尝试将存储库推送到 Amazon Elastic Beanstalk 时,“aws.push”不是 git 命令
使用 MacOSX 将 Rails 应用程序推送到 AWS Elastic Beanstalk
Amazon S3 无法通过 Cloudfront 上传文件