寻找理想的设置,将 nginx 作为我们的顶层负载均衡器,在多个 Varnish 实例之间分配负载。
分配此负载的最佳方法是什么?一种方法是简单地将其均匀地分配到各个实例,另一种方法是根据请求 URL 模式分配负载。有没有最佳实践?
此外,我们遇到一种情况,需要手动(从后端)清除缓存中的特定项目。最有效的方法是向我们的每个 Varnish 实例发出一个小的 HTTP“PURGE”请求吗?
答案1
分配此负载的最佳方法是什么?一种方法是简单地将其均匀地分配到各个实例,另一种方法是根据请求 URL 模式分配负载。有没有最佳实践?
视情况而定。您希望基于 URL 哈希之类的内容进行分发的原因有两个:
- 缓存大小。如果您缓存的数据总体上足以填满给定后端的缓存,那么让某个 URL 始终命中同一个后端会很有帮助,这样可以在后端之间分配缓存数据的存储,而不是存储重复的数据。
- 丢失请求/缓存生命周期的速度。如果客户端请求丢失缓存是一个问题,并且缓存持续时间不长,如果给定的内容始终命中给定的 Varnish 服务器,则丢失的次数可能会减少。
此外,我们遇到一种情况,需要手动(从后端)清除缓存中的特定项目。最有效的方法是向我们的每个 Varnish 实例发出一个小的 HTTP“PURGE”请求吗?
这种方法可行,但会导致下一个内容请求者出现潜在的缓慢缓存未命中。另一种方法是使用 Varnishreq.hash_always_miss
强制更新缓存中的资源,而不是直接使其无效,这样外部请求就不会被迫未命中。
因此你的 vcl 中存在类似这样的内容:
acl purge {
"localhost";
}
sub vcl_recv {
/* add this into your existing config: */
if (req.http.X-Varnish-Nuke == "1" && client.ip ~ purge) {
set req.hash_always_miss = true;
}
}
然后,设置了该标头的请求将强制后端请求更新缓存中的内容(使用 curl 或 wget,--header "X-Varnish-Nuke: 1"
)。