Setting up your caching strategy and tactics is done in part to avoid having to use your backends too much. You need a backend to cache objects in the first place. Using Varnish to manage your backends and configure access to them is another way that you can take control over performance-related matters.
First and foremost, you will want to introduce the backend to Varnish. There are two ways to do this automatically: By adding a backend to your VCL file or by omitting VCL completely and using the -b flag at startup time.
A VCL backend definition is easy; all you need are the host address and the port the backend is listening on:
backend default {
.host = "127.0.0.1";
.port = "8080";
}
However, there are often multiple backends, and you want to be able to control which request goes to which backend. You can
define multiple backends and use req.backend_hint to assign a backend other than the default one. By incorporating the req.backend_hint variable in our VCL logic, we can perform content-aware load balancing so that each backend can be tuned to its specific task.
Backend health
A basic backend health check can easily be undertaken.
You can view the health of your backends by executing the following command: varnishadm backend.list
This could be the output of that command:
boot.public |
probe |
Healthy 10/10 |
boot.admin |
probe |
Healthy 10/10 |
Both backends are listed and their health is automatically checked by a probe (you can read up on how to analyze health probes in the Varnish Book). In the example above, the backend is considered healthy because 10 out of 10 checks were successful. You can define what you consider a healthy backend for your Varnish setup as the health probe is configurable.
Directors
A director is a built-in VMOD (Varnish module) that groups several backends and presents them as one. Directors offer different decision-making strategies to decide which request is handled by which backend. The goal of directors is to avoid backend latency by distributing requests across multiple backends: by balancing out backend requests, backend servers will experience
less load, which reduces latency for horizontal scalability.
Besides pure load balancing, directors also make sure that unhealthy backend nodes are not used, routing requests to, another healthy node, making up a high availability strategy.
In order to use directors, you first need to import the directors VMOD and initialize it in vcl_init.
There are different director distribution strategies, such as round-robin, which distributes loads equally, and each backend takes its turn sequentially.
Here’s an example of a round-robin director declaration that uses three backends:
sub vcl_init {
new loadbalancing = directors.round_robin();
loadbalancing.add_backend(backend1);
loadbalancing.add_backend(backend2);
loadbalancing.add_backend(backend3);
}
After we declare the director, it needs to be assigned in vcl_recv:
sub vcl_recv {
set req.backend_hint = loadbalancing.backend();
}
Round-robin is a good approach, but it is not suitable for every situation. For example, in cases in which your backend servers don’t have the same server resources, you would be forcing the server with the least amount of memory or CPU to share an equal load with better-resourced servers.
There are several other useful directors in Varnish, including random director, hash director, and the fallback director, which you can learn about in the O'Reilly book "Getting started with Varnish Cache”.
Clearly you will want to set your directors up for maximum stability and resilience, but in cases where no backend is available, what happens? You either end up delivering nothing (which is a no-go situation for most businesses), or at least delivering the last-known-good version. This is where Grace mode comes in. In Varnish you can assign a certain period of grace time, letting Varnish serve objects in cache beyond their TTL. These objects will continue to be served as long as there’s no updated object for a duration defined by the grace time. In many cases, Grace mode has ensured that end-users barely notice, if they notice at all, any “hiccups” in content being served.
{{ parent.title || parent.header.title}}
{{ parent.tldr }}
{{ parent.linkDescription }}
{{ parent.urlSource.name }}