HAproxy: mapping process to CPU core for maximum performance

This article was updated in 2018 to reflect new options. See at the bottom.

HAproxy 1.5 being long in development, introduced many new features. Two of them are in particular interesting for me: encryption offloading and binding processes to CPU cores.

Since version 1.5 it is possible to offload all encryption to your HAproxy servers and save some resources on your application servers, that do not need to perform encryption anymore. This is quite easy to configure as it only require to add ssl option to bind section of HAproxy config, like that:

bind 0.0.0.0:5222 ssl crt /etc/yourdomain.pem

you can go further with tuning SSL, like selecting ciphers, adding multiple certificates for domains (SNI support) and other ssl/tls features. More details can be found in manual.

On multi-core systems, this setup however can cause problems, as HAproxy is single-threaded - especially on virtual servers like Amazon EC2 and others that give their users many low-power CPU cores that performance per core do not increases - when you buy faster instance you actually get more cores - and in case of Amazon, this is fixed value of 3.25 ECU per core (for m3 instances).

This of course causes that HAproxy will have similar performance no matter how big instance is selected. Since version 1.5-dev13 HAproxy offers to split processes and map them to CPU cores. There are 2 options that need to be set: nbproc and cpu-map. To be accurate, nbproc is not new option, it was in 1.4 as well, but now you have control over it which core is doing what.

Here is example of simple configuration for system with 4 cores:

global
    nbproc 4
    cpu-map 1 0
    cpu-map 2 1
    cpu-map 3 2
    cpu-map 4 3

First number is process starting with “1” and second is CPU core starting with “0”. Above setup will cause haproxy to spread load on all 4 cores equally. But this is just a beginning. You can dedicate only some cores to perform specified operations, for example, for HTTP traffic you would use only 1 dedicated core while 3 other cores can do HTTPS, just add bind-process directive:

frontend access_http
   bind 0.0.0.0:80
   bind-process 1
frontend access_https
   bind 0.0.0.0:443 ssl crt /etc/yourdomain.pem
   bind-process 2 3 4

You can even separate CPU cores for backend processing. More details as always can be found in haproxy user manual for version 1.5 here

2018 UPDATE

Since this article was written over 4 years ago, HAproxy have introduced new threading model and new options to spread the load across CPU. Since version 1.8 HAproxy is fully multi-threaded. To enable multithreaded mode just add:

nbthread 4

to global section. Here we allow HAproxy to use 4 threads. Is is worth of mention that nbthread and nbproc are compatibile so you can start 2 separate processes with selected numbers of threads beneath them:

nbproc 2
nbthread 4

This was posted 10 years ago. It has 0 notes.