I'm planning to have an architecture similar to:

  nginx - nginx - nginx - nginx
    \       \       /       /
    /           |         \
app server - app server - app server

(The app servers are all "identical" in the sense that a request can be routed to any of them by Varnish.) The varnish in that diagram would be processing (potentially) hundreds of thousands of requests per second. Can it do that?

I'd prefer to run multiple Varnish servers, for failover and performance reasons, but the immediate problem I see is that caching wouldn't have much use, because each request would hit a different Varnish server, until each of the Varnish servers had a copy of the cached object. What's the right way to do this? (Again, the app servers are identical to Varnish, it doesn't matter to which the request is routed. I'd like to have multiple Varnish servers (behind nginx's load balancing) processing the requests.)


I recently dealt with the same question. Varnish can handle quite a lot of requests per second, but you should test it with your setup (hardware, network, size of responses, hit ratio) to get an idea about performance numbers. Besides performance, there's the matter of failover to start balancing.

  • if urls are your cache key, you can setup a mechanism in nginx that chooses a specific varnish instance based on the url (varnish_instance = hash(url) modulo nr_of_varnishes). If varnish rewrites the url before it forwards it to a back-end or does a cache lookup, and different urls get rewritten to the same new url, then this trick isn't effective.

  • in my case I can't route based on the url at the loadbalancer. We use lvs-dr and simply don't know about the url at the balancer.

  • I've played with the idea to setup such a distribution mechanism in varnish. One could configure the other varnishes as 'back-ends', calculate a hash and route the request to the right varnish. The 'right' varnish does the back-end call and stores it in cache. Other varnishes could store the results as well but don't have to. This setup makes your varnish configuration more complicated, so think carefully before choosing such a path. Direct Routing (part of lvs-dr) makes it even more complicated.

In the end I chose a simple solution: distribute requests over 2 big varnish instances without any smart stuff. Results are calculated and cached twice, but varnish configurations were kept as simple as possible.

  • 1
    there is the "upstream consistent hash" module available for nginx. If you used this with URLs as they key, the cache hit ratio on multiple varnish instances would improve drastically, and content would not get duplicated unless one of the varnish instances failed. The failure behavior would be "soft" as well, with each remaining varnish instance seeing the same increase in load and new objects. wiki.nginx.org/NginxHttpUpstreamConsistentHash – rmalayter Sep 9 '10 at 3:56
  • @rmalayter +1 for the "upstream consistent hash" module for nginx, or similar functionality for any other load balancer. That's the best way to go -- with N reverse proxies they will each handle 1/N of the URL address space. – Jesper M Sep 16 '10 at 0:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.