Varnish : Cluster - Purge cache on all varnish hosts

391 Views Asked by At

I am using the (free) version of varnsih (version 6).

Here is my configuration :

  • 2 varnish hosts (varnish_A, varnish_B)
  • 2 webs servers (node_A, node_B)

I only cache all the pages /app/api/client (GET) from my web servers and it's working very well

But I have a problem, when there is an update on the page (from a PUT) /app/api/client/test_data I added a BAN in the sub vcl_recv part

if (req.url ~ "^app/api/client($|/.*)" &&  ( req.method == "POST" || req.method == "PUT" ))  {
ban("req.http.host == " + req.http.host + " && req.url == " + req.url);
std.syslog(180, "[debug]["+req.method+"] - Starting Purge of the cache for: " + req.http.host + req.url );
return (pass);
set req.backend_hint = web_node.backend();
}

The ban is working, but only on the current varnish host (for example varnish_B), so the other one (varnish_A) still has the old version of the object...

Does any one know how to "share" the ban on all host ?

Thank you !

1

There are 1 best solutions below

4
Thijs Feryn On

Send a ban to both Varnish servers

It's just a matter of running the ban on both Varnish servers, rather than on one. You can probably build that into your content management flow where the 2 endpoints are called.

Varnish Broadcaster

Alternatively you could sign up for Varnish Enterprise and use the Varnish Broadcaster as your banning endpoint. It will distribute the request to all or to specific Varnish nodes. See https://docs.varnish-software.com/varnish-broadcaster/examples/ for examples.

Optimizing your bans

Just a sidenote, using req.url and req.http.host is not ideal for bans. When the ban is executed, the ban lurker doesn't have access to these variables, which means the banning is the responsibility of the next request.

A way to circumvent this limitation is by adding the following VCL code:

sub vcl_backend_response {
    set beresp.http.x-url = bereq.url;
    set beresp.http.x-host = bereq.http.host;
}

sub vcl_deliver {
    unset resp.http.x-url;
    unset resp.http.x-host;
}

You could then run the following ban:

ban("obj.http.x-host ~ " + req.http.host + " && obj.http.x-url == " + req.url);

See https://www.varnish-software.com/developers/tutorials/ban/ for a full tutorial on Varnish bans.