All things Sysadmin
Just another manic Monday

Multiple backends with Varnish

September 15th, 2008 by Erik Ljungstrom

Varnish has been able to provide caching for more than one backend for quite some time. The achilles heel with this has up until now been that it hasn’t been able to determine whether a backend is healthy or not. This is now a problem of the past! The backend health polling code is available in 2.0 beta1 Sadly it had a bug, so when using the ‘random’ director, it was unable to use the remaining healthy backend if all but one went MIA. I reported this bug and it was fixed in changeset r3174.

So as of now, you can safely use one varnish instance for several front-ends, thus eliminate double-caching (memory waste, unnecessary load on back-ends), reduce network traffic, do rudimentary load balancing, ease management etc.
With the obscene amount of traffic Varnish can push without putting a fairly basic system under any load worth mentioning, you can use a single front-end to serve several nodes in most setups.

Here’s an elementary sample VCL for how to do this:

backend node0 {
  .host = "127.0.0.1";
  .port = "80";
  .probe = {
           .url = "/";
           .timeout = 50 ms;
           .interval = 1s;
           .window = 10;
           .threshold = 8;

  }
}

backend node1 {
  .host = "10.0.0.2";
  .port = "80";
  .probe = {
#           .url = "/";
           .timeout = 100 ms;
           .interval = 1s;
           .window = 10;
           .threshold = 8;
        .request =
            "GET /healthcheck.php HTTP/1.1"
            "Host: 10.0.0.2"
            "Connection: close"
            "Accept-Encoding: foo/bar" ;
  }
}
director cl1 random {
    { .backend = node0; .weight = 1; }
    { .backend = node1; .weight = 1; }
}

#director cl1 round-robin {
#   { .backend = node1; }
#   { .backend = node0; }
#}

sub vcl_recv {
        set req.backend = cl1;
}



As you can see I’m defining the backends slightly differently. You need to define one of .url or .request, but not both for obvious reasons. If you go for the slighly simpler .url the default request looks like this:

GET / HTTP/1.1
Host: something
Connection: close


If this does not suit your need, comment out .url and use .request to roll your own. This aspect of Varnish is actually quite well documented, so I won’t repeat what’s on the trac page.

There is clearly a lot more you can and, more often than not, should do in the VCL than the above. This is a stripped down version which only pertains to the backend polling functionality.

Posted in Webservers, misc

2 Responses

  1. Vito

    Hi,
    good article, but are you sure about the “.weight” directive?

    I try to make a little balancer but Varnish (2.0.2) seems not recognize the “.weight” field with an explicity error.

    V.

  2. Erik

    Vito,

    I’m sure, I just set it up with -trunk and it works fine there too. The error isn’t necessarily to do with .weight, it may be somewhere else in your VCL. Join #varnish on irc.linpro.no or raise a ticket on the Varnish trac if you still have problems.

    Cheers,
    Erik

Leave a Comment

Please note: Comment moderation is enabled and may delay your comment. There is no need to resubmit your comment.