我对使用 nginx 或 varnish 还不是很熟练,但这是我目前的设置。
我有一个正在运行的 node.js 服务器,它提供 json、html 模板或 socket.io 事件。然后我在 node 前面运行 nginx,它提供所有静态内容(css、js 等)。
此时,我想将静态内容和动态内容都缓存到内存中。
据我所知,Varnish 可以很好地缓存静态内容,而且不需要触及我的应用程序代码。我还认为它也能缓存动态内容,但不能有任何 cookie 标头?
我目前确实使用 redis 来保存会话数据,并计划将来将它用于其他用途,比如跟踪非关键但有趣的统计数据。
我只是不知道该如何处理网站上的所有内容的缓存。我认为这取决于这些选项,但可能还有更多:
将 varnish 放在 nginx 前面,让 varnish 缓存静态页面,无需更改应用程序代码。Redis 将缓存动态数据库调用,这需要修改我的应用程序代码。
完全忽略使用 varnish,让 redis 处理所有缓存,然后使用其中一个 nginx-redis 模块。我不确定这是否需要大量更改应用程序代码(对于静态文件)。
我没有找到可以比较 nginx+varnish 和 nginx+redis 的基准测试,而且我也没有经验,无法自己进行基准测试(我的配置很可能很糟糕)。
我基本上是在寻找在请求/秒方面最有效且将来可扩展的解决方案(用新硬件解决问题+可能在配置中调整某些值=新服务器半无痛地启动并运行)。
答案1
对于纯静态内容,在任何成熟的 Web 服务器(如 nginx 或 Apache)之前运行 Varnish 通常不会带来太大的优势。(我不能代表 node.js 发言,因为我还没有用过它。)原因是内核维护一个文件系统缓存,将最近访问的文件存储在 RAM 中。Varnish 在选择确切的哪个哪些文件要保留在缓存中,哪些文件要弹出,但也可能做得更糟。这取决于您的系统还做了什么以及缓存保留策略的差异。在 Web 服务器前面使用代理所导致的额外延迟将远远超过 Varnish 和内核文件系统缓存之间的任何差异。
你是正确的Varnish 不缓存通过Set-Cookie:
标头发送的响应如果请求包含标Cookie:
头,它还会跳过查看缓存。这样做的原因是,对于访问任何给定页面的每个用户,都会有一个这样的唯一响应,并且每个用户不太可能再次访问同一页面,这意味着您的缓存将充满永远不会使用的实体。
漆能缓存动态内容,这就是它的亮点所在。假设您网站的首页需要编译 PHP 代码和 20 个冷缓存上的数据库查询。在热缓存(APC、memcached、Redis、MySQL 查询缓存等)上,它仍然需要查找 memcached/Redis 并对stat()
请求中包含的每个 PHP 文件执行查询。假设您的网站优化得相当好,这仍然可能至少需要 1/10 秒(这已经是相当优化了;根据我的经验,1-3 秒是更常见的)。Varnish 可以在千分之一秒内愉快地提供相同的页面。但这意味着您的用户无法登录您网站的首页,因为他们无法获取他们的Cookie:
标题,但如果您可以接受,Varnish 是您的不二之选。
清漆也需要正确的缓存标头。如果不确定缓存对象是否安全,则不会缓存。如果您满足所有这些要求,Varnish 可能是适合您的工具。也就是说,只要将正确的标头放到位,客户端就会自己缓存内容,这比 Varnish 的效果要好得多。
如果你缺乏亲自对设置进行基准测试的经验,那么现在是时候获得这种经验了。你正在通过基准测试来衡量配置的适当性。尝试一些东西并运行ab
它,然后更改一事情并ab
以完全相同的方式针对该配置运行。现在您知道哪一个“更好”。冲洗,重复。(此外,始终运行ab
两次并忽略第一个结果。这将确保您只测试热缓存,并且不会错误地认为一个配置更糟糕,因为它是针对冷缓存测试的。)
为您的网站构建可扩展的解决方案是一个相当复杂的话题,无法用 ServerFault 的答案来概括。当您遇到这些问题时,我们当然可以为您提供帮助(例如“如何将我的 memcached 服务器扩展到 memcached 集群?”)。
进一步阅读:
我之前写过一个答案,其中有一节是关于在基准测试中发现瓶颈。Womble
最近向我指出一篇关于寻找瓶颈的优秀文章。