编者按 — 本文是有关大容量和高可用性缓存的系列博文的第一篇:
- 使用 NGINX Plus 缓存集群共享缓存 — 第 1 部分(本文)
- 使用 NGINX Plus 缓存集群共享缓存 — 第 2 部分
本文已更新,用 NGINX Plus API 取代了之前单独的扩展状态模块。
如何使用 NGINX 或 NGINX Plus 构建大容量、高可用的缓存集群呢?本系列博文(共两篇)介绍了两种新方法。本文为其中第一篇,您可以点击上面的链接查看第二篇。(除非另有说明,否则该方法同样适用于 NGINX 开源版和 NGINX Plus,但为简洁起见,在此仅提及 NGINX Plus)。
NGINX Plus 缓存概述
NGINX Plus 可作为代理缓存服务器运行 — 位于源服务器和远程客户端之间,负责管理传入源服务器的流量,并缓存(存储)常用的不变资源。这样,当客户端请求这些资源时,NGINX Plus 就能直接做出响应,从而减少源服务器的负载。NGINX Plus 的代理缓存最常部署在靠近源服务器的数据中心,也可以类似于 CDN 的方式部署在全球分布式 PoP 中。
内容缓存是一个颇为复杂的话题。在继续阅读本文之前,不妨先熟悉一些基本的缓存技术:
- NGINX Plus 缓存的机制 – 核心配置以及缓存加载器和缓存管理器进程的作用
- 微调缓存时间 – 执行微缓存等操作,以控制内容缓存的方式以及内容过期时的刷新方式
为何 NGINX Plus 不使用共享磁盘进行缓存?
每台 NGINX Plus 服务器都是独立的 Web 缓存服务器。目前尚无可在多台 NGINX Plus 服务器之间共享基于磁盘的缓存的技术手段,这是一项有意的设计决策。
在不可靠的高延迟共享文件系统上存储缓存并非明智的设计选择。NGINX Plus 对磁盘延迟很敏感,尽管 线程池功能可卸载主线程的 read()
和 write()
操作,但当文件系统运行缓慢且缓存 I/O 较高时,NGINX Plus 可能会被大量线程淹没。要跨 NGINX Plus 实例维护一致的共享缓存还需要集群范围的锁定机制,以同步填充、读取和删除等重叠的缓存操作。最后,共享文件系统会给缓存带来潜在的不可靠性和不可预测性,而这两者对于缓存而言至关重要。
为何要在多台 NGINX Plus 服务器之间共享缓存?
尽管共享文件系统不是缓存的好方法,但在多台 NGINX Plus 服务器之间缓存内容有时也很有必要:
- 如果您的主要目标是创建一个超大容量的缓存,则可跨多台服务器对缓存进行分片(分区)。我们将在本文中介绍这项技术。
- 如果您的主要目标是实现高可用性,同时最大限度地减少源服务器的负载,那么请使用高可用的共享缓存。有关此技术,请参阅下一篇博文(即将发布)。
对缓存进行分片
对缓存进行分片是在多台 Web 缓存服务器之间分配缓存条目的过程。NGINX Plus 缓存分片使用一致性哈希算法为每个缓存条目选择一台缓存服务器。图中显示了当一台服务器发生故障(中图)或添加另一台服务器(右图)时,跨三台服务器(左图)分片的缓存会发生什么变化。
总缓存容量是各服务器缓存容量之和。由于针对每个资源只有一台服务器会尝试进行缓存(同一资源不会有多个独立副本),因此您可以最大限度地减少访问源服务器的次数。
这种模式具有容错性,因为如果您有 N 台缓存服务器,而其中一台发生了故障,则只会丢失 1/N 的缓存。该“丢失部分”会再通过一致性哈希均匀分配给其余的 N –1 台服务器。相比之下,更简单的哈希方法会将全部缓存重新分配给其余服务器,而在重新分配过程中,您几乎会丢失所有缓存。
在执行一致性哈希负载均衡时,使用缓存键(或用于构建该键的字段的子集)作为一致性哈希的键:
upstream cache_servers {
hash $scheme$proxy_host$request_uri consistent;
server red.cache.example.com;
server green.cache.example.com;
server blue.cache.example.com;
}
您可以使用 NGINX Plus 中的主动-被动高可用性解决方案、轮询 DNS 或 keepalived
等高可用性解决方案在负载均衡器 (LB) 层中分发传入的流量。
优化分片缓存配置
您可选择两种优化方式中的任意一种来优化缓存分片配置。
结合使用负载均衡器层和缓存层
您可以结合使用负载均衡器层和缓存层。在此配置中,每个 NGINX Plus 实例上运行两台虚拟服务器。负载均衡虚拟服务器(图中的“LB VS”)接受来自外部客户端的请求,并使用一致性哈希将这些请求分配给集群中的所有 NGINX Plus 实例(通过内部网络连接)。每个 NGINX Plus 实例上的缓存虚拟服务器(“Cache VS”)在其内部 IP 地址上监听相应份额的请求,然后将请求转发给源服务器并缓存响应。这样一来,所有 NGINX Plus 实例均可充当缓存服务器,从而最大限度地提高缓存容量。
配置一级“热”缓存
另外,您还可以在前端负载均衡器层上为热内容配置一级缓存,使用大型共享缓存作为二级缓存。这有助于提高性能,并可在二级缓存层出现故障时降低对源服务器的影响,因为只需在一级缓存内容逐渐过期时刷新内容即可。
如果缓存集群正在处理很大量的热内容,那么较小的一级缓存上的内容刷新率可能会很高。换句话说,对缓存中有限空间的需求太高,以致内容被很快从缓存中删除(以便为最近请求的内容腾出空间),甚至无法用于满足随后的请求。
上述情况的一个标志是已提供内容占已写入的内容的比例较低。这两项指标都包含在NGINX Plus API 模块报告的扩展统计数据中,并显示在内置的实时活动监控仪表盘上 Caches(缓存)选项卡的 Served(已缓存)和 Written(已写入)字段中。(请注意,NGINX Plus API 模块和实时活动监控仪表盘在 NGINX 开源版中不可用。)
该屏幕截图显示的情况是,NGINX Plus 写入缓存的内容多于从缓存中提供的内容:
在本例中,您可以对缓存进行微调,只存储最常请求的内容。 proxy_cache_min_uses
指令可帮助识别这些内容。
总结
跨多个 NGINX 或 NGINX Plus Web 缓存服务器对缓存进行分片是创建大容量、可扩展缓存的一种有效方法。一致性哈希提供了出色的高可用性,可确保在一个缓存出现故障时,只有这一份缓存内容会失效。
本系列博文的第二篇介绍了另一种共享缓存模式,即在一对 NGINX 或 NGINX Plus 缓存服务器上复制缓存。总容量受限于单台服务器的容量,但配置具有完全容错能力,即使一台缓存服务器不可用,也不会丢失任何缓存内容。
如欲在您自己的服务器上尝试进行缓存分片,请立即下载 30 天免费试用版 ,或与我们联系以讨论您的用例。