博客 | NGINX

使用 NGINX Plus 缓存集群实现共享缓存,第 1 部分

NGINX-F5-horiz-black-type-RGB 的一部分
欧文·加勒特缩略图
欧文·加勒特
2017 年 1 月 24 日发布

编辑器——这是有关高容量和高可用性缓存的系列文章的第一部分:

这篇文章已更新,参考了 NGINX Plus API,它取代并弃用了最初在此处讨论的单独的扩展状态模块。

如何使用 NGINX 或 NGINX Plus 构建大容量、高可用性的缓存集群? 这是由两部分组成的系列文章中的第一部分,介绍了实现这一目标的替代方法。 您可以通过上面的链接访问第二部分。 (除非另有说明,这些方法同样适用于 NGINX Open Source 和 NGINX Plus,但为了简洁起见,我们仅提及 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 缓存分片到多个服务器可最大程度地提高缓存容量,而共享高可用性 Web 缓存可最大程度地降低源服务器上的负载

缓存分片

分片缓存是将缓存条目分布在多个 Web 缓存服务器的过程。 NGINX Plus 缓存分片使用一致性哈希算法为每个缓存条目选择一个缓存服务器。 图表显示了当一台服务器发生故障(中间图)或添加另一台服务器(右图)时,分布在三台服务器上的缓存(左图)发生的情况。

在对跨三个 Web 缓存服务器的缓存启用一致性缓存后,发生故障的服务器上的缓存数据将分布在剩余的服务器中,而新添加的服务器将从每个现有服务器接管部分数据

总缓存容量为各服务器缓存容量之和。 您可以最大限度地减少前往原始服务器的次数,因为只有一台服务器尝试缓存每个资源(您没有同一资源的多个独立副本)。

在 Web 缓存服务器上对缓存进行分片可创建容错配置,其中每个资产仅缓存在一台服务器上

这种模式具有容错能力,如果您有N 个缓存服务器,其中一个发生故障,那么您只会丢失 1/ N的缓存。 该“丢失部分”由一致性哈希均匀分布在剩余的N -1 台服务器上。 更简单的散列方法会在剩余的服务器上重新分配整个缓存,并且在重新分配期间您会丢失几乎所有的缓存。

当你执行一致性哈希负载均衡时,使用缓存键(或用于构造键的字段子集)作为一致性哈希的键:

上游缓存服务器 { hash $scheme$proxy_host$request_uri consistent;

服务器 red.cache.example.com;
服务器 green.cache.example.com;
服务器 blue.cache.example.com;
}

您可以使用NGINX Plus 中的主动被动高可用性解决方案、循环 DNS 或keepalived等高可用性解决方案在负载均衡器 (LB) 层之间分配传入流量。

优化分片缓存配置

您可以选择两种方式对缓存分片配置进行优化。

结合负载均衡器和缓存层

您可以组合 LB 和缓存层。 在这种配置中,每个 NGINX Plus 实例上运行两个虚拟服务器。 负载平衡虚拟服务器(图中为“LB VS”)接受来自外部客户端的请求,并使用一致性哈希将它们分发到集群中通过内部网络连接的所有 NGINX Plus 实例。 每个 NGINX Plus 实例上的缓存虚拟服务器(“Cache VS”)都会在其内部 IP 地址上监听其请求份额,然后将其转发到原始服务器并缓存响应。 这允许所有 NGINX Plus 实例充当缓存服务器,从而最大限度地提高缓存容量。

在每个 NGINX Plus 实例上运行负载平衡虚拟服务器和缓存虚拟服务器可最大程度地提高 Web 缓存的容量

配置一级“热”缓存

或者,您可以在前端 LB 层上为非常热门的内容配置一级缓存,并使用大型共享缓存作为二级缓存。 如果第二级缓存层出现故障,这可以提高性能并减少对原始服务器的影响,因为只需要在第一级缓存内容逐渐过期时刷新内容。

如果第二级 Web 缓存服务器发生故障,则在负载平衡层上配置第一级缓存可减少对源服务器的影响

如果您的缓存集群正在处理大量热门内容,您可能会发现较小的一级缓存的流失率非常高。 换句话说,对缓存中有限空间的需求如此之高,以至于内容在能够用于满足哪怕一个后续请求之前就被从缓存中逐出(以便为最近请求的内容腾出空间)。

这种情况的一个指标是服务内容与书面内容的比例较低,这两个指标包含在NGINX Plus API模块报告的扩展统计数据中。 它们出现在内置实时活动监控仪表板“缓存”选项卡上的“服务”“写入”字段中。 (请注意, NGINX Plus API模块和实时活动监控仪表板在 NGINX 开源中不可用。)

此屏幕截图显示了 NGINX Plus 向缓存写入的内容多于从缓存中提供的内容的情况:

NGINX Plus 实时活动监控仪表板上的“缓存”选项卡揭示了不良情况,即写入缓存的数据多于从缓存中读取的数据

在这种情况下,您可以微调缓存以仅存储最常请求的内容。 proxy_cache_min_uses指令可以帮助识别此内容。

概括

跨多个 NGINX 或 NGINX Plus Web 缓存服务器分片缓存是创建高容量、可扩展缓存的有效方法。 一致性哈希提供了良好的高可用性,确保如果缓存失败,则只有其缓存内容的份额会失效。

这篇文章的第二部分描述了一种替代的共享缓存模式,它在一对 NGINX 或 NGINX Plus 缓存服务器上复制缓存。 总容量受限于单个服务器的容量,但配置具有完全容错能力,如果缓存服务器不可用,缓存内容也不会丢失。

在您自己的服务器上尝试缓存分片 - 立即开始30 天免费试用联系我们讨论您的用例


“这篇博文可能引用了不再可用和/或不再支持的产品。 有关 F5 NGINX 产品和解决方案的最新信息,请探索我们的NGINX 产品系列。 NGINX 现在是 F5 的一部分。 所有之前的 NGINX.com 链接都将重定向至 F5.com 上的类似 NGINX 内容。”