我有一个运行 nginx / php-fpm / varnish / wordpress 和 amazon s3 的系统。
现在,我在设置系统时查看了很多配置文件,并且在所有文件中我都发现了类似这样的内容:
/* If the request is for pictures, javascript, css, etc */
if (req.url ~ "\.(jpg|jpeg|png|gif|css|js)$") {
/* Remove the cookie and make the request static */
unset req.http.cookie;
return (lookup);
}
我不明白为什么要这样做。大多数示例也将 NginX 作为 Web 服务器运行。现在的问题是,为什么要使用 varnish 缓存来缓存这些静态文件。
对我来说,仅缓存动态文件更有意义,这样 php-fpm / mysql 就不会受到太多影响。
我是否正确或者我遗漏了什么?
更新
我想根据给出的答案为问题添加一些信息。
如果你有一个动态网站,内容实际上变化很大,缓存就毫无意义了。但是如果你使用 WordPress 来创建静态网站,则可以缓存很长时间。
话虽如此,对我来说更重要的是静态内容。我找到了一个链接,其中包含一些针对不同缓存应用程序和 Web 服务器应用程序的测试和基准测试。
http://nbonvin.wordpress.com/2011/03/14/apache-vs-nginx-vs-varnish-vs-gwan/
NginX 在获取静态内容方面实际上更快,因此让它通过更有意义。NginX 非常适合处理静态文件。
--
除此之外,大多数时候静态内容甚至不在 Web 服务器本身中。大多数时候,这些内容存储在某个 CDN 上,可能是 AWS S3 之类的。我认为 varnish 缓存是你最不想存储静态内容的地方。
答案1
Varnish 有几个优点。您注意到的第一个优点是减少后端服务器的负载。通常通过缓存动态生成但很少更改的内容(与访问频率相比)。以您的 Wordpress 为例,大多数页面可能不会经常更改,并且存在一些插件,可以在页面更改时(即新帖子、编辑、评论等)使 Varnish 缓存无效。因此,您可以无限期地缓存,并在更改时使其无效 - 这会将后端服务器的负载降至最低。
尽管有链接的文章,大多数人还是认为如果设置正确,Varnish 的性能会优于 Nginx - 尽管(我真的不愿意承认) - 我自己的测试似乎也同意 nginx 可以比 varnish 更快地提供静态文件(幸运的是,我不会将 varnish 用于此目的)。我认为问题在于,如果您最终使用 Varnish,那么您已经在设置中添加了一个额外的层。通过该额外层传递到后端服务器总是比直接从后端提供服务要慢 - 这就是为什么允许 Varnish 缓存可能会更快的原因 - 您节省了一个步骤。另一个优势是在磁盘 io 方面。如果您将 varnish 设置为使用 malloc,则根本不会触及磁盘,这使它可用于其他进程(并且通常会加快速度)。
我认为需要更好的基准测试才能真正衡量性能。反复请求相同的单个文件会触发文件系统缓存,从而开始将焦点从 Web 服务器本身转移。更好的基准测试将使用 siege 和几千个随机静态文件(甚至可能来自您的服务器日志)来模拟真实的流量。不过,正如您所提到的,将静态内容卸载到 CDN 已经变得越来越普遍,这意味着 Varnish 可能一开始就不会提供它(您提到了 S3)。
在实际情况下,您可能会优先考虑内存使用情况 - 首先是动态内容,因为生成动态内容的成本最高;然后是小型静态内容(例如 js/css),最后是图像 - 您可能不会在内存中缓存其他媒体,除非您有充分的理由这样做。在这种情况下,如果 Varnish 从内存加载文件,而 nginx 从磁盘加载文件,那么 Varnish 的性能可能会优于 nginx(请注意,nginx 的缓存仅用于代理和 fastCGI,默认情况下这些缓存基于磁盘 - 尽管可以将 nginx 与 memcached 一起使用)。
(我的快速 - 非常粗略,不具有任何可信度 - 测试表明 nginx(直接)是最快的 - 我们称之为 100%,varnish(使用 malloc)稍慢(约 150%),varnish(使用 pass)后面的 nginx 是最慢的(约 250%)。这说明了一切 - 全有或全无 - 增加额外的时间(和处理)来与后端通信,只是表明如果您使用 Varnish,并且有足够的 RAM,您不妨缓存所有可以缓存的内容并从 Varnish 提供它,而不是传回 nginx。)
答案2
我觉得你可能遗漏了一些东西。
根据定义,动态文件会发生变化。通常,它们会通过执行某种数据库查询来更改,从而影响提供给用户的页面内容。因此,您不想缓存动态内容。如果您这样做,它只会变成静态内容,而且很可能是内容不正确的静态内容。
举一个简单的例子,假设您有一个页面,页面顶部显示登录用户的用户名。每次加载该页面时,都会运行数据库查询以确定请求该页面的登录用户的用户名,以确保显示正确的名称。如果您要缓存此页面,则数据库查询不会发生,所有用户都会在页面顶部看到相同的用户名,并且很可能不是他们的用户名。您需要在每次加载页面时都进行该查询,以确保向每个用户显示正确的用户名。因此它不可缓存。
将此逻辑扩展到更成问题的东西(例如用户权限),您就会明白为什么动态内容不应被缓存。如果数据库没有找到动态内容,CMS 就无法确定请求页面的用户是否有权查看该页面。
静态内容按定义对所有用户而言都是相同的。因此,无需进行数据库查询即可为每个用户定制该页面,因此缓存该页面以消除不必要的数据库查询是有意义的。图像是静态内容的一个非常好的例子 - 您希望所有用户都看到相同的标题图像、相同的登录按钮等,因此它们是缓存的绝佳候选对象。
在上面的代码片段中,您会看到一个非常典型的 Varnish VCL 片段,它强制缓存图像、css 和 javascript。默认情况下,Varnish 不会缓存任何带有 cookie 的请求。逻辑是,如果请求中有 cookie,那么服务器一定有某种原因需要该 cookie,因此后端需要它并且必须通过缓存传递。实际上,许多 CMS(Drupal、Wordpress 等)将 cookie 附加到几乎所有东西上,无论是否需要,因此编写 VCL 以从已知为静态的内容中删除 cookie 是很常见的,这反过来会导致 Varnish 缓存它。
合理?
答案3
为了动态内容例如,股票报价等某些类型的数据实际上经常变化(每秒更新一次SaaS server
)backend server
,但查询频率可能会更高(数以万计subscription clients
):
[stock calculation / backend server] ----- [SaaS server] ------ [subscription clients]
在这种情况下,缓存SaaS server
每秒的更新使得满足backend servers
数以万计的查询成为可能subscription users
。
如果 SaaS 服务器上没有缓存,那么这种模型就无法工作。
答案4
使用 Varnish 缓存静态文件有利于减轻 Nginx 的负担。当然,如果您有大量静态文件需要缓存,则会浪费 RAM。不过,Varnish 有一个很好的功能 - 它支持多个缓存存储后端。
对于静态文件:缓存到 HDD 对于其他所有内容:缓存到 RAM。
这应该能让你更深入地了解如何实现这个场景:http://www.getpagespeed.com/server-setup/varnish-static-files-cache