Comparing Nginx and HAProxy for web applications

Archive

Mo Tu We Th Fr Sa Su
12345
6789101112
13141516171819
20212223242526
272829


Poll: Social Media

Which social media you used ?

  • email Email to a friend
  • print Print version
  • Add to your del.icio.us del.icio.us
  • Digg this story Digg this
  • Facebook

Did you enjoy this article?

(total 2 votes)
Adjust font size: Decrease font Enlarge font
Comparing Nginx and HAProxy for web applications The last few days I have been comparing Nginx to HAProxy, with surprising results.

First, a bit of background. For a long time we at Indowebster have been using Nginx as the main web server for our projects like indowebster.com. Nginx is a superb little open-source web server with a small footprint, sensible configuration language, modern feature set and buckets of speed. However, we quickly realized that the load balancing features of the proxy are not up to scratch.

The core problem is the proxy load balancing algorithm. Nginx only comes with a round-robin balancer and a hash-based balancer. Only the former is of interest to us since our object is to distribute the load evenly across a pack of Mongrel back ends. The round-robin algorithm is often an acceptable tool: if every request finishes within a few milliseconds, there’s no problem.

But if a page takes a while to load, Nginx will start routing requests to backends that are already processing requests — as a result, some backends will be queueing up requests while some backends will remain idle. You will get an uneven load distribution, and the unevenness will increase with the amount of load subject to the load-balancer.

Unfortunately, patch is not completely stable, and turned out to be the main source of our stability problems of late. Sometimes it sits down chewing the carpet while backends go idle and requests pile up, or worse, goes into tailspin and refuses to serve requests, for which the only remedy is a cold restart of Nginx. Even in normal operation, however, it will often send multiple connections to a backend even when some are idle, since there is no limit on the number of connections each backend can receive.

After reading about HAProxy, I felt the itch to try out this product myself. HAProxy has a handsome feature set:

    * It’s is proxy — and only a proxy. It can’t serve files, for example: proxying is all its does.
    * It can proxy anything TCP-based — not just HTTP.
    * Plenty of load-balancing algorithms, including a "least connections" strategy that picks the backend with the fewest pending connections. Which happens to be just what we want.
    * Backends can be sanity- and health-checked by URL to avoid routing requests to brain-damaged backends. (It can even stagger these checks to avoid spikes.)
    * A dedicated status page gives you backend status, uptime and lots of yummy metrics. There’s also a way to read metrics from a Unix domain socket.
    * Requests can be routed based on all sorts of things: cookies, URL substrings, client IP, etc.

I like the fact that HAProxy is so single-minded in its approach. Experience tells me that simple, specialized, single-purpose applications are preferable over complex, flexible one-size-fits-all applications, Varnish and Memcached being two relevant examples.

To determine if HAProxy is up to par, I have done a few simple benchmarks. They’re not awesomely scientific, but I think they are good enough.

The setup: Dedicated test machine, 4 servers running an actual APACHE app. I use Apache’s ab benchmarking tool for the testing (many people prefer httperf, but we have never quite seen eye to eye) and I run 1,000 requests at various levels of concurrency. The page being tested is a minimal controller action that makes one database call, one Memcached lookup and renders an empty page; it takes about 20ms to render.


I have configured HAProxy with the "leastconns" algorithm and "maxconn 1" ?. This is intentionally unfair — but the object is not a comparison of HAProxy and Nginx when each is configured identically; rather, I would like to observe what kind of performance profile can be achieved with HAProxy’s superior gadgetry.

The "maxconns" setting is significant — since only a single request is handed to APACHE at a time, it means that when all backends are busy, pending client requests will idle inside HAProxy — rather than inside Mongrel. Subsequently, when a backend becomes available, the next request in line will be routed to that backend. Without this restriction, of course, requests would end up in busy APACHE and sit there even though other backends might be available.

Nginx, using the fair load-balancing patch, will behave similarly, but will suffer occasionally overlapping requests since it has no limit on the number of connections each back end can receive.

Glad to share to Indonesian Webmaster.
blog comments powered by Disqus
  • email Email to a friend
  • print Print version
  • Add to your del.icio.us del.icio.us
  • Digg this story Digg this
  • Facebook

Semua yang ada pada website ini adalah ilmu, bacaan dan opini pribadi dalam journal hidup kami di Internet.
© 2000-2010 Gembels.com by dono a.k.a Widhe