NGINX.COM

编者按 — 本文是有关大容量和高可用性缓存的系列博文的第一篇:

本文已更新,用 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 服务器都是独立的 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 天免费试用版 ,或与我们联系以讨论您的用例

Hero image
《NGINX 完全指南》2024 年最新完整版


高性能负载均衡的进阶使用指南

关于作者

Owen Garrett

产品管理高级总监

Owen is a senior member of the NGINX Product Management team, covering open source and commercial NGINX products. He holds a particular responsibility for microservices and Kubernetes‑centric solutions. He’s constantly amazed by the ingenuity of NGINX users and still learns of new ways to use NGINX with every discussion.

关于 F5 NGINX

F5, Inc. 是备受欢迎的开源软件 NGINX 背后的商业公司。我们为现代应用的开发和交付提供一整套技术。我们的联合解决方案弥合了 NetOps 和 DevOps 之间的横沟,提供从代码到用户的多云应用服务。访问 nginx-cn.net 了解更多相关信息。