NGINX Full Version

借助 NGINX Plus 缓存集群实现缓存共享,第 1 部分

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

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