Multiple backends with Varnish

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.

About Erik Ljungstrom

I'm Erik Ljungstrom and I work in a datacenter as a technical team leader. In this blog I will mostly jot down things I consider noteworthy things I encounter in my work. For more information, please see http://northernmost.org
This entry was posted in misc, Webservers and tagged , , . Bookmark the permalink.

2 Responses to Multiple backends with Varnish

  1. Vito says:

    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 says:

    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 Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>