NGINX Full Version

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

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

如何使用 NGINX 或 NGINX Plus 构建大容量、高可用的缓存集群呢?本文介绍了如何使用两台或多台 NGINX 或 NGINX Plus 缓存服务器创建高可用的缓存集群。(除非另有说明,否则本文介绍的方法同样适用于 NGINX 开源版和 NGINX Plus,但为简洁起见,在此仅提及 NGINX Plus。)

 

回顾 — 分片缓存解决方案

本系列博文的第一篇介绍了大型分片缓存集群的创建模式。

当您需要创建一个可自由扩展的大容量缓存时,该模式非常有效。由于每个资源仅缓存至一台服务器,因此配置不具备完全容错能力,但一致性哈希负载均衡可确保在一台服务器发生故障时,只有这一份缓存内容会失效。

 

创建高可用的缓存集群

如果您的主要目标是尽量最大限度地减少源服务器请求数,那么缓存分片解决方案并非最佳选择。相比之下,包含主辅 NGINX Plus 实例的解决方案才能满足您的要求:

NGINX Plus 主实例接收所有流量,并将请求转发至辅助实例。辅助实例从源服务器检索内容并对其进行缓存;主实例也会缓存来自辅助实例的响应,并将其返回给客户端。

两台设备都有完整的缓存,并根据您配置的超时时间刷新缓存。

配置主缓存服务器

配置主缓存服务器,将所有请求转发到辅助服务器并缓存响应。 如上游组中server 指令的 backup 参数所示,如果辅助服务器发生故障,主服务器会直接将请求转发到源服务器:

proxy_cache_path /tmp/mycache keys_zone=mycache:10m;

server {
    status_zone mycache;          # for NGINX Plus extended status

    listen 80;

    proxy_cache mycache;
    proxy_cache_valid 200 15s;

    location / {
        proxy_pass http://secondary;
    }
}

upstream secondary {
    zone secondary 128k;          # for NGINX Plus extended status

    server 192.168.56.11;         # secondary
    server 192.168.56.12 backup;  # origin
}

配置辅助缓存服务器

配置辅助缓存服务器,将请求转发到源服务器并缓存响应。

proxy_cache_path /tmp/mycache keys_zone=mycache:10m;

server {
    status_zone mycache;          # for NGINX Plus extended status

    listen 80;

    proxy_cache mycache;
    proxy_cache_valid 200 15s;

    location / {
        proxy_pass http://origin;
    }
}

upstream origin {
    zone origin 128k;            # for NGINX Plus extended status

    server 192.168.56.12;        # origin
}

配置高可用

最后,您需要配置高可用 (HA),以便在主服务器发生故障时,由辅助服务器接收传入流量;主服务器恢复后会再接回流量。

在本例中,我们使用 NGINX Plus 的主动-被动高可用性解决方案。对外发布的虚拟 IP 地址为 192.168.56.20,主缓存服务器充当高可用集群的主节点。如果您使用的是 NGINX 开源版,则可手动安装并配置 keepalived 或其他高可用性解决方案。

 

故障切换方案

我们希望创建一个高可用的缓存集群,即使一台缓存服务器发生故障,集群也能继续运行。我们不希望增加源服务器的负载,无论是在缓存服务器发生故障时,还是在缓存服务器恢复并需要刷新过期内容时。

假设主服务器发生故障, NGINX Plus 高可用解决方案会将外部 IP 地址切换到辅助服务器。

辅助服务器拥有完整的缓存,并继续正常运行,不会增加源服务器的负载。

当主缓存服务器恢复并开始接收客户端流量时,不仅其缓存已过期,而且许多条目也已过期。主服务器将从辅助缓存服务器刷新其本地缓存;因为辅助缓存服务器上的缓存是最新缓存,所以不会增加源服务器的流量。

现在,假设辅助服务器发生故障。主服务器检测到这一情况(使用高可用性解决方案的健康检查特性),直接将流量转发到备用服务器(即源服务器)。

主服务器拥有完整的缓存,并继续正常运行。同样,这也不会增加源服务器的负载。

当辅助服务器恢复时,其缓存已过期。不过,它只会在主服务器的缓存过期时接收来自主服务器的请求,此时辅助服务器缓存的副本也已过期。即使辅助服务器需要向源服务器发出内容请求,也不会增加对源服务器的请求频率。这对源服务器没有任何不利影响。

 

测试故障切换行为

为了测试高可用解决方案,我们将源服务器配置为记录请求返回每个请求的当前时间。这意味着源服务器的响应每秒都在变化:

access_log /var/log/nginx/access.log;

location / {
    return 200 "It's now $time_localn";
}

主辅缓存服务器已配置为将状态代码为 200 的响应缓存 15 秒。这通常会让缓存每 15 或 16 秒更新一次。

proxy_cache_valid 200 15s;

验证缓存行为

我们每秒向缓存集群的高可用性虚拟 IP 地址发送一次 HTTP 请求。在主辅服务器上的缓存过期且从源服务器刷新响应之前,响应不会改变。响应每 15 或 16 秒改变一次。

$ while sleep 1 ; do curl http://192.168.56.20/ ; done
It's now 9/Feb/2017:06:35:03 -0800
It's now 9/Feb/2017:06:35:03 -0800
It's now 9/Feb/2017:06:35:03 -0800
It's now 9/Feb/2017:06:35:19 -0800
It's now 9/Feb/2017:06:35:19 -0800
^C

我们还可以检查源服务器上的日志,确认源服务器是否每 15 或 16 秒才会收到一个请求。

验证故障切换

我们可以通过中止主服务器或辅助服务器(例如中止 nginx 进程),验证故障切换是否正常运行。恒定负载测试继续运行,并持续缓存响应。

检查源服务器上的访问日志,确认无论哪台缓存服务器发生故障或恢复,源服务器每 15-16 秒才会收到一个请求。

缓存更新时间

在稳定的情况下,缓存的内容通常每 15-16 秒更新一次。内容会在 15 秒后过期,在收到下一个请求之前会有最多 1 秒的延迟,触发缓存更新。

有时,缓存的更新速度会较慢(内容变更的间隔时间长达 30 秒)。如果主缓存服务器的内容过期,并且主缓存服务器从辅助缓存服务器检索的缓存内容即将过期,就会出现这种情况,对此您可在辅助服务器上配置较短的缓存超时时间。

 

总结

本文介绍了如何在两台或两台以上 NGINX 缓存服务器之间分层缓存,这是创建高可用缓存集群的一种有效方法,可最大限度地降低源服务器的负载,从而在其中一台缓存服务器发生故障或恢复时保护它们免受流量激增的影响。

缓存的总容量受限于单台缓存服务器的容量。本系列博文的第一篇介绍了另一种分片缓存模式,该模式在缓存服务器集群中对缓存进行分区。在这种情况下,总容量是所有缓存服务器容量之和,但内容不会重复缓存,以防止在一台缓存服务器发生故障时源服务器的流量激增。

如欲在您自己的服务器上尝试创建高可用缓存,请立即下载 30 天免费试用版,或与我们联系以讨论您的用例