HAProxy 1.8.0 released, Web load balancing
HAProxy provides high availability, load balancing, and proxies for TCP and HTTP-based applications that support virtual hosting, a free, fast, and reliable solution. Over the years it has become the de-facto standard opensource load balancer, is now shipped with most mainstream Linux distributions, and is often deployed by default in cloud platforms.
HAProxy involves several techniques commonly found in Operating Systems architectures to achieve the absolute maximal performance :
- a single-process, event-driven model considerably reduces the cost of context switch and the memory usage. Processing several hundreds of tasks in a millisecond is possible, and the memory usage is in the order of a few kilobytes per session while memory consumed in preforked or threaded servers is more in the order of megabytes per process.
- O(1) event checker on systems that allow it (Linux and FreeBSD) allowing instantaneous detection of any event on any connection among tens of thousands.
- Delayed updates to the event checker using a lazy event cache ensures that we never update an event unless absolutely required. This saves a lot of system calls.
- Single-buffering without any data copy between reads and writes whenever possible. This saves a lot of CPU cycles and useful memory bandwidth. Often, the bottleneck will be the I/O busses between the CPU and the network interfaces. At 10-100 Gbps, the memory bandwidth can become a bottleneck too.
- Zero-copy forwarding is possible using the splice() system call under Linux, and results in real zero-copy starting with Linux 3.5. This allows a small sub-3 Watt device such as a Seagate Dockstar to forward HTTP traffic at one gigabit/s.
- MRU memory allocator using fixed size memory pools for immediate memory allocation favoring hot cache regions over cold cache ones. This dramatically reduces the time needed to create a new session.
- Work factoring, such as multiple accept() at once, and the ability to limit the number of accept() per iteration when running in multi-process mode, so that the load is evenly distributed among processes.
- CPU-affinity is supported when running in multi-process mode, or simply to adapt to the hardware and be the closest possible to the CPU core managing the NICs while not conflicting with it.
- Tree-based storage, making heavy use of the Elastic Binary tree I have been developping for several years. This is used to keep timers ordered, to keep the runqueue ordered, to manage round-robin and least-conn queues, to look up ACLs or keys in tables, with only an O(log(N)) cost.
- Optimized timer queue : timers are not moved in the tree if they are postponed, because the likeliness that they are met is close to zero since they’re mostly used for timeout handling. This further optimizes the ebtree usage.
- optimized HTTP header analysis : headers are parsed an interpreted on the fly, and the parsing is optimized to avoid an re-reading of any previously read memory area. Checkpointing is used when an end of buffer is reached with an incomplete header, so that the parsing does not start again from the beginning when more data is read. Parsing an average HTTP request typically takes half a microsecond on a fast Xeon E5.
- careful reduction of the number of expensive system calls. Most of the work is done in user-space by default, such as time reading, buffer aggregation, file-descriptor enabling/disabling.
- Content analysis is optimized to carry only pointers to original data and never copy unless the data needs to be transformed. This ensures that very small structures are carried over and that contents are never replicated when not absolutely necessary.
HAProxy 1.8.0 official version has been released.
Changelog
– BUG/MEDIUM: stream: don’t automatically forward connect nor close
– BUG/MAJOR: stream: ensure analysers are always called upon close
– BUG/MINOR: stream-int: don’t try to read again when CF_READ_DONTWAIT is set
– MEDIUM: mworker: Add systemd `Type=notify` support
– BUG/MEDIUM: cache: free callback to remove from tree
– CLEANUP: cache: remove unused struct
– MEDIUM: cache: enable the HTTP analysers
– CLEANUP: cache: remove wrong comment
– MINOR: threads/atomic: rename local variables in macros to avoid conflicts
– MINOR: threads/plock: rename local variables in macros to avoid conflicts
– MINOR: threads/atomic: implement pl_mb() in asm on x86
– MINOR: threads/atomic: implement pl_bts() on non-x86
– MINOR: threads/build: atomic: replace the few inlines with macros
– BUILD: threads/plock: fix a build issue on Clang without optimization
– BUILD: ebtree: don’t redefine types u32/s32 in scope-aware trees
– BUILD: compiler: add a new type modifier __maybe_unused
– BUILD: h2: mark some inlined functions “unused”
– BUILD: server: check->desc always exists
– BUG/MEDIUM: h2: properly report connection errors in headers and data handlers
– MEDIUM: h2: add a function to emit an HTTP/1 request from a headers list
– MEDIUM: h2: change hpack_decode_headers() to only provide a list of headers
– BUG/MEDIUM: h2: always reassemble the Cookie request header field
– BUG/MINOR: systemd: ignore daemon mode
–More…
Download
Sources: http://www.haproxy.org/download/1.8/src/
Git repository: http://git.haproxy.org/git/haproxy-1.8.git/
Git Web browsing: http://git.haproxy.org/?p=haproxy-1.8.git